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

Любой совет приветствуется

4 ответа

Решение

Да это именно проблема при использовании flask-sqlalchemy модели, смешанные с чистым sqlalchemy сессия. Дело в том, что flask-sqlalchemy подклассы базы Session от sqlalchemy и добавляет некоторые внутренние, один из которых является _model_changes ДИКТ. Этот 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 

У меня была такая же проблема, как и у вас, так что надеюсь, это поможет вам.

ОБНОВИТЬ:

Доступна новая версия, которая должна исправлять это поведение, цитируя документы 2.0:

Изменено, как подписываются встроенные сигналы, чтобы пропустить сеансы не Flask-SQLAlchemy. Это также исправит ошибку атрибута о несуществующих изменениях модели.

Документы: http://flask-sqlalchemy.pocoo.org/2.0/changelog/

У меня была такая же проблема, и я решил ее, изменив класс _SessionSignalEvents в init.py в flask-sqlalchemy. Однако я только что заметил, что такое исправление уже существует с 8 месяцев в официальном хранилище.

Если вы столкнулись с подобной проблемой, я бы порекомендовал вам удалить последнюю версию проекта с github ( https://github.com/mitsuhiko/flask-sqlalchemy/), так как та, которая в настоящее время доступна через pip install, устарела.

Я решил эту проблему, обменяйтеsession.execкsession.execute. Я не делал глубокого анализа по этому поводу. Я думаю, это связано с тем, чтоSessionMakerвозвращенный объект, который не является оригинальнымSession

Версия SQLAlchemy==1.4.x у меня не работает.

Однако измените на SQLAlchemy == 1.3.18, и это сработало.

Как создать такой файл, чтобы указать установленные версии?

  1. pip3 замораживание > требования.txt
  2. pip3 установить колбу
  3. pip3 установить колбу-sqlalchemy

Отредактируйте файл requirements.txt и запись SQLAlchemy , например, SQLAlchemy==1.3.18.

Затем повторно запустите виртуальную среду. --> прогон фляги

Если вы не установили виртуальную среду?

  • python3 -m venv .venv
  • источник .venv/bin/активировать
  • прогон фляги

Надеюсь, это поможет !

Другие вопросы по тегам