drop_all()在Flask中使用SQLAlchemy冻结

时间:2014-06-18 15:43:25

标签: python flask

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

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

def setUp(self):
    # other stuff...
    myapp.db.drop_all()
    myapp.db.create_all()
    # db creation...

这适用于第一次测试,但在第二次测试运行之前它会在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)

任何人都知道如何解决这个问题?

4 个答案:

答案 0 :(得分:27)

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...

答案 1 :(得分:6)

只需关闭应用中的所有会话,然后再调用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)

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

答案 2 :(得分:0)

我有同样的问题,在我的情况下,我有2个不同的会话对同一个表进行查询。我的解决方案是在两个地方都使用一个scoped_session。

我在一个不同的模块中创建它,所以我没有循环依赖的问题,像这样:

db.py:

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()

models.py:

from .db import db
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)

app.py:

from flask import Flask
from .db import db
app = Flask(__name__)
db.init_app(app)

在所有代码中仅使用db.session将保证您处于同一会话中。在测试中,请确保在tearDown执行回滚。

答案 3 :(得分:0)

我是Flask开发人员,并使用flask_sqlalchemy和pytest测试我的Web应用程序,当db.drop_all()我的表将显示我的一个表被锁定时,我遇到了类似的情况。

因此,在db.drop_all()解决我的问题之前,我使用db.session.remove()删除了会话。