Я попытался полностью разделить Flask и SQLAlchemy с помощью this method, но Flask все еще, кажется, способен обнаружить мою базу данных и начать новую транзакцию в начале каждого запроса.Как Flask запускает новую транзакцию SQLAlchemy в начале каждого запроса?
db.py
файл создает новую сессию и определяет простую модель стола:
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String
engine = create_engine("mysql://web:[email protected]/web_unique")
print("creating new session")
db_session = scoped_session(sessionmaker(bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
# define model of 'persons' table
class Person(Base):
__tablename__ = "persons"
name = Column(String(30), primary_key=True)
def __repr__(self):
return "Person(\"{0.name}\")".format(self)
# create table
Base.metadata.create_all(bind=engine)
И app.py
, простое приложение Колба с помощью сеанса SQLAlchemy и модель:
from flask import Flask, escape
app = Flask(__name__)
# importing new session
from db import db_session, Person
# registering for app teardown to remove session
@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
@app.route("/query")
def query():
# query all persons in the database
all_persons = Person.query.all()
print all_persons
return "" # we use the console output
if __name__ == "__main__":
app.run(debug=True)
Бежим это:
$ python app.py
creating new session
* Running on http://127.0.0.1:5000/
* Restarting with reloader
creating new session
Вейдер достаточно ru нс db.py
два раза, но мы просто игнорировать это, давайте доступ к веб-странице /query
:
[]
127.0.0.1 - - [23/Dec/2015 18:20:14] "GET /query HTTP/1.1" 200 -
Мы можем видеть, что наш запрос ответили, что мы используем только консольный вывод. Там нет в базе данных нет Person
еще, давайте добавим один:
mysql> INSERT INTO persons (name) VALUES ("Marie");
Query OK, 1 row affected (0.11 sec)
Marie
является частью базы данных сейчас, чтобы мы перезагрузить страницу:
[Person("Marie")]
127.0.0.1 - - [23/Dec/2015 18:24:48] "GET /query HTTP/1.1" 200 -
Как вы можете видеть сеанс уже знает о Marie
, Фланец не создал новый сеанс. Это означает, что началась новая транзакция. Сравните это с примером плана python ниже, чтобы увидеть разницу.
Мой вопрос в том, как Flask может начать новую транзакцию в начале каждого запроса. Флакон не должен знать о базе данных, но, похоже, может что-то изменить в своем поведении.
В случае, если вы не знаете, что сделка SQLAlchemy считывают этот пункт, извлеченный из Managing Transactions:
Когда транзакционный состояние завершается после отката или фиксации, высвобождает сессии все транзакции и ресурсы подключения, а возвращается в состояние «начать», которое снова вызовет новое соединение и объекты Транзакции, так как новые запросы на выдачу операторов SQL получат .
Таким образом, транзакция завершается фиксацией и создаст новое соединение, которое затем сделает сеанс снова прочитанным в базе данных.На самом деле это означает, что вы должны совершить, если вы хотите, чтобы увидеть изменения, внесенные в базу данных:
Первый в интерактивном режиме Python:
>>> from db import db_session, Person
creating new session
>>> Person.query.all()
[]
коммутатора к MySQL и вставить новый Person
:
mysql> INSERT INTO persons (name) VALUES ("Paul");
Query OK, 1 row affected (0.03 sec)
Наконец попытаться загрузить Paul
в нашей сессии:
>>> Person.query.all()
[]
>>> db_session.commit()
>>> Person.query.all()
[Person("Paul")]
'db.py' запускается два раза [из-за перегружателя] (http://stackoverflow.com/a/25504196/978961). – dirn