如何创建单独的文件以生成数据库Flask-SqlAlchemy的不同表?

时间:2019-02-01 08:02:31

标签: python sqlalchemy flask-sqlalchemy flask-migrate

我使用Flask-Restplus和SqlAlchemy创建我的表和Api,我面临的问题如下:

起初,我有这个user.py,里面有2个表:

User.py

class User(db.Model):
    __tablename__ = "users_info"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.Integer, unique=True, nullable=True)
    device = db.relationship('Device', backref='user')
    # .. some other field here


class Device(db.Model):
    __tablename__ = "user_device"

    device_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    id = db.Column(db.Integer, db.ForeignKey(User.id))
    # .. some other field here

这时,我将下面的这2个命令与manage.py一起使用来创建数据库,并且没有问题。

python manage.py db migrate

python manage.py db upgrade

manage.py

import os
import unittest

from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from app import blueprint

from app.main import create_app, db

app = create_app(os.getenv('My_App') or 'dev')
app.register_blueprint(blueprint)

app.app_context().push()

manager = Manager(app)

migrate = Migrate(app, db)

manager.add_command('db', MigrateCommand)


@manager.command
def run():
    app.run()


if __name__ == '__main__':
    manager.run()

现在,我想创建另一个名为product.py的文件,它是同一数据库的新表,如下所示:

Product.py

from .. import db
from .model.user import User


class Product(db.Model):
    __tablename__ = "product"

    product_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    product_name = db.Column(db.String)
    # plan here what you want in this table
    user_id = db.Column(db.Integer, db.ForeignKey(User.user_id))

您可以看到Product类与User的{​​{1}}有关系。

结果:

但是我使用上面的相同命令再次迁移,结果看起来像这样:

foreignKey

似乎没有从我的新文件中检测到新表。

我的问题:

如何创建单独的文件以生成不同的数据库表?

1 个答案:

答案 0 :(得分:1)

我认为问题在于没有导入模型,这意味着SQLAlchemy和Alembic不了解它们。

这对某些人来说是违反直觉的,但是SQLAlchemy使用内省来找出定义了哪些模型,因此在许多情况下,解决问题的方法是仅将模型导入到主脚本中,即使您不需要使用它们。导入它们将使它们对SQLAlchemy和Alembic可见,并且从那里一切将正常运行。

以您为例,您只需要在manage.py中添加如下内容:

from model.user import User
from model.product import Product

如果由于循环依赖关系而导致导入错误,则可能需要将导入向下移动到所有其他导入下方。如果您在同一脚本中定义db实例,则您希望这些导入位于定义数据库的行下,因为显然需要首先定义数据库。