Flask-SQLAlchemy 单元测试失败 InvalidRequestError: 表 '{table_name}' 已为此元数据实例定义

sil*_*ger 5 python sqlalchemy flask flask-sqlalchemy

我正在使用 Flask、SQLAlchemy 构建 API 服务,最近还集成了 Flask-SQLAlchemy 扩展。虽然我可以独立运行应用程序并成功进行 API 调用,但在尝试运行单元测试时遇到了问题。我认为问题在于多次导入 db.Model 类型。

例外是这样的:

Error
Traceback (most recent call last):
  File "/Users/james/.pyenv/versions/2.7.10/lib/python2.7/unittest/case.py", line 322, in run
    self.setUp()
  File "/Users/james/Documents/workspace/trustmile-backend/trustmile/tests/test_users.py", line 28, in setUp
    from trustmile.app.users.model import User, ConsumerUser, CourierUser, AuthSession, Location, UserAddress, db
  File "/Users/james/Documents/workspace/trustmile-backend/trustmile/app/users/model.py", line 23, in <module>
    class User(db.Model, UniqueMixin, TableColumnsBase, References):
  File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 536, in __init__
    DeclarativeMeta.__init__(self, name, bases, d)
  File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 55, in __init__
    _as_declarative(cls, classname, cls.__dict__)
  File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 88, in _as_declarative
    _MapperConfig.setup_mapping(cls, classname, dict_)
  File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 103, in setup_mapping
    cfg_cls(cls_, classname, dict_)
  File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 131, in __init__
    self._setup_table()
  File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 394, in _setup_table
    **table_kw)
  File "/Users/james/.virtualenvs/trustmile-api-p2710/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 398, in __new__
    "existing Table object." % key)
InvalidRequestError: Table 'tmuser' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
Run Code Online (Sandbox Code Playgroud)

我在 /app/ (顶层)中的init .py 如下所示:

__author__ = 'james'

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

import config
from app.messaging import EmailHandler

app = Flask(__name__, static_folder='api/static', static_url_path='/static')
app.config.from_object(config)

db = SQLAlchemy(app)

EmailHandler.setup(config.EMAIL_API_KEY_DEV)
from app.api.consumer_v1 import bp as blueprint
app.register_blueprint(blueprint, url_prefix = '/consumer/v1')
app.test_request_context()
Run Code Online (Sandbox Code Playgroud)

运行它:

from app import app
app.run(debug=True, host='0.0.0.0', port=5001)
Run Code Online (Sandbox Code Playgroud)

效果很好。

我的 test_users.py 的开头如下所示:

__author__ = 'james'
from trustmile.app.exc import InvalidEmailException
from trustmile.app.exc import InsecurePasswordException
from nose.tools import assert_true, raises
from trustmile.app.users.model import User, ConsumerUser, CourierUser, AuthSession, Location, UserAddress, db
from . import TransactionalTest



email_address = 'james@cloudadvantage.com.au'
test_password = 'mypassword'


class UserTest(TransactionalTest):



    @classmethod
    def setUpClass(cls):
        super(UserTest, cls).setUpClass()

    def setUp(self):
        super(UserTest, self).setUp()

    def test_create_user(self):
        user = User()
        db.session.add(user)
Run Code Online (Sandbox Code Playgroud)

这一定是进行单元测试的相当常见的方法,是的,我在模块之间共享 SQLAlchemy 对象(我确信这是不好的做法)。我正在使用鼻子测试运行它,并且在代码初始化时发生错误。抱歉问了这么长的问题,希望有人能帮助我!

小智 0

__table_args__ = {'extend_existing': True}
Run Code Online (Sandbox Code Playgroud)

就在下面__tablename__