Sqlalchemy flask: AttributeError: объект "Session" не имеет атрибута "_model_changes" на session.commit()
Я видел много проблем с SessionMaker, но это немного отличается. Не уверен, почему, но sqlalchemy не позволит моему объекту сеанса совершить.
В моем приложении у меня есть код, который делает:
views.py
rec = session.query(Records).filter(Records.id==r).first()
n = rec.checkoutRecord(current_user.id)
session.add(n)
session.commit()
models.py:
class Records(UserMixin, CRUDMixin, Base):
__table__ = Table('main_records', Base.metadata, autoload=True)
def checkoutRecord(self,uid):
self.editing_uid = uid
self.date_out = datetime.now()
return self
def checkinRecord(self,uid):
self.editing_uid = uid
self.date_in = datetime.now()
return self
Программа завершает фиксацию(), предоставляя исключение выше. Интересно, что некоторый тестовый код, который не импортирует флягу, но импортирует sqlalchemy, прекрасно работает и позволяет мне совершать ошибки без ошибок.
Полная трассировка стека:
Traceback (most recent call last):
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask_login.py", line 663, in decorated_view
return func(*args, **kwargs)
File "/Users/bhoward/projects/PeerCoUI/mk2/peercoui/app/records/views.py", line 65, in select_view
session.commit()
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 149, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 721, in commit
self.transaction.commit()
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 354, in commit
self._prepare_impl()
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 323, in _prepare_impl
self.session.dispatch.before_commit(self.session)
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/event.py", line 372, in __call__
fn(*args, **kw)
File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 162, in session_signal_before_commit
d = session._model_changes
AttributeError: 'Session' object has no attribute '_model_changes'
Полный код проекта находится в github: https://github.com/bhoward00/peercoui
Любые советы, оцененные
Ответы
Ответ 1
Да, это точно проблема при использовании моделей flask-sqlalchemy
, смешанных с чистым сеансом sqlalchemy
. Дело в том, что flask-sqlalchemy
подклассы базы Session
из sqlalchemy
и добавляет некоторые внутренние элементы, одним из которых является _model_changes
dict. Этот dict используется для отслеживания модификации модели.
Итак, если вы хотите использовать модели на основе flask-sqlalchemy
с обычным сеансом sqlalchemy
, одним из способов было бы просто добавить dict в сеанс (это всего лишь пример кода):
def create_session(config):
engine = create_engine(config['DATABASE_URI'])
Session = sessionmaker(bind=engine)
session = Session()
session._model_changes = {}
return session
У меня была такая же точная проблема, как и вы, поэтому, надеюсь, это вам поможет.
UPDATE:
Доступна новая версия, которая должна исправлять это поведение, цитируя 2.0 docs:
Изменено, как встроенные сигналы подписываются, чтобы пропускать сеансы без флажка-SQLAlchemy. Это также исправит ошибку атрибута о том, что изменения модели не существуют.
Документы: http://flask-sqlalchemy.pocoo.org/2.0/changelog/#version-2-0
Ответ 2
У меня была такая же проблема, и я решил ее, изменив класс _SessionSignalEvents в init.py в flask-sqlalchemy. Тем не менее, я только заметил, что такое исправление уже существует с 8 месяцев в официальном репозитории.
Если у вас возникнет аналогичная проблема, я бы посоветовал вам вытащить последнюю версию проекта из github (https://github.com/mitsuhiko/flask-sqlalchemy/), поскольку один из доступных в настоящее время через pip install устарел.