Flask-SQLAlchemy的create_all不会创建表

时间:2018-04-13 15:56:19

标签: python unit-testing flask sqlalchemy flask-sqlalchemy

我正在研究烧瓶应用程序,我试图隔离我的单元测试。我正在使用flask-sqlalchemy,我试图在运行测试后使用create_alldrop_all方法清理我的数据库。

但是,正如文档所述,我的create_alldrop_all方法似乎并未实际创建/删除表。就像大多数其他答案所说的那样,我在调用create_all之前在应用程序中导入了我的模型。

这是我在下面的代码中遇到的错误:

psycopg2.ProgrammingError: relation "tasks" does not exist

这是我的相关代码

/app.py

import os
import configparser

from flask import Flask
from src.router import router

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app = Flask(__name__)

if not os.path.exists(os.path.join(app.root_path, 'config.ini')):
    raise Exception(f'config.ini not found in the {app.root_path}')

config = configparser.ConfigParser()
config.read('config.ini')

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = config[os.environ['APP_ENV']]['DATABASE_URI']

app.register_blueprint(router)

db = SQLAlchemy(app)
migrate = Migrate(app, db)

if __name__ == "__main__":
    app.run()

/tests/test_router.py

from unittest import TestCase

from flask import Flask
from app import app, db
from src.models import Task

class TestRouter(TestCase):

    def setUp(self):
        db.create_all()

    def tearDown(self):
        db.drop_all()

    def test_adds_task(self):
        task = Task(task_id='task_1', name='my task')
        db.session.add(task)
        db.session.commit()

1 个答案:

答案 0 :(得分:0)

我认为我发布这个问题的速度有点快,但我希望这可以帮助其他人就如何解决类似问题提出其他想法。

在我保留模型的src/models.py文件中,您必须确保正确定义模型。由于Flask-SQLAlchemy是SQLAlchemy的包装器,因此必须使用db对象下的数据类型。

基本上,我的模型定义如下:

class Task(db.Model):
    __tablename__ = 'tasks'

    id = Column(Integer, primary_key=True)
    task_id = Column(String)
    name = Column(String)
    created_at = Column(DateTime, default=datetime.datetime.now)

如您所见,我继承自db.Model而不是declarative_base()的返回值。我还需要在所有数据类型前面添加db.,包括ColumnIntegerStringFloatDateTimerelationshipForeignKey

所以,我能够通过将我的模型更改为:

来解决我的问题
class Task(db.Model):
    __tablename__ = 'tasks'

    id = db.Column(db.Integer, primary_key=True)
    task_id = db.Column(db.String)
    name = db.Column(db.String)
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)

请参阅:Documentation on declaring Flask-SQLAlchemy models