drop_all()在Flask中使用SQLAlchemy冻结

mir*_*ngu 27 python flask

我正在为Flask应用程序编写测试用例.

我有一个setUp方法,它会在重新创建它们之前删除db中的表.它看起来像这样:

def setUp(self):
    # other stuff...
    myapp.db.drop_all()
    myapp.db.create_all()
    # db creation...
Run Code Online (Sandbox Code Playgroud)

这适用于第一次测试,但它在drop_all第二次测试运行之前冻结.

编辑: 当中断进程时,堆栈跟踪看起来像这样

  File "populate.py", line 70, in create_test_db
    print (myapp.db.drop_all())
  File ".../flask_sqlalchemy/__init__.py", line 864, in drop_all
    self._execute_for_all_tables(app, bind, 'drop_all')
  File ".../flask_sqlalchemy/__init__.py", line 848, in _execute_for_all_tables
    op(bind=self.get_engine(app, bind), tables=tables)
  File ".../sqlalchemy/sql/schema.py", line 3335, in drop_all
  ....
  File "/Library/Python/2.7/site-packages/MySQLdb/cursors.py", line 190, in execute
    r = self._query(query)
Run Code Online (Sandbox Code Playgroud)

任何人都有一个线索如何解决这个问题?

mir*_*ngu 33

Oki,可能还有其他解决方案但是现在,在搜索了互联网之后,我发现如果我在前面添加一个代码,问题就会消失myapp.db.session.commit().我猜,某个交易正在等待提交.

def setUp(self):
    # other stuff...
    myapp.db.session.commit()   #<--- solution!
    myapp.db.drop_all()
    myapp.db.create_all()
    # db creation...
Run Code Online (Sandbox Code Playgroud)

  • 与postgres相同的问题. (3认同)

小智 10

只需关闭应用中的所有会话,然后再调用drop_all

    def __init__(self, conn_str):
        self.engine = create_engine(conn_str)
        self.session_factory = sessionmaker(engine)

    def drop_all(self):
        self.session_factory.close_all() # <- don't forget to close
        Base.metadata.drop_all(self._engine)
Run Code Online (Sandbox Code Playgroud)

有关SQLAlchemy中的会话的更多信息 http://docs.sqlalchemy.org/en/latest/orm/session_api.html?highlight=close_all

  • 请注意,对于 SQLAlchemy 1.3,“Session.close_all() 方法已弃用,并将在未来版本中删除。” 新命令是:“from sqlalchemy.orm.session import close_all_sessions”,然后是“close_all_sessions()”。 (4认同)
  • 你真是个了不起,不可思议,美妙,可爱,美丽的人。非常感谢。 (3认同)

Bra*_*ang 5

我是一名 Flask 开发人员,使用 Flask_sqlalchemy 和 pytest 来测试我的应用程序服务器,当我运行该语句时,我遇到了类似的情况db.drop_all(),控制台显示我的一个表已锁定。

我习惯db.session.remove()在运行 db.drop_all() 之前删除会话。