简体   繁体   English

在 Flask-SQLAlchemy 中,我应该使用 create_all() 在生产环境中创建表吗?

[英]In Flask-SQLAlchemy, Should i use create_all() to create tables in production environment?

I am new to Flask.我是 Flask 的新手。 I am working on Flask-SQLAlchemy,and i also tried Flask-Migrate.我正在研究 Flask-SQLAlchemy,我也尝试过 Flask-Migrate。

It's handy to create production and test environments quickly.快速创建生产和测试环境非常方便。

But i think it's not as convenient as Django-Migration .但我认为它不如Django-Migration方便。

When i tried to create many-to-many data model.当我尝试创建多对多数据模型时。 I got following error sometimes:有时我会收到以下错误:

sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1215, 'Cannot add foreign key constraint') [SQL: u'
    CREATE TABLE ad_accounts (
    access_token_id INTEGER, 
    ad_account_id INTEGER, 
    FOREIGN KEY(access_token_id) REFERENCES fb_access_token (id), 
    FOREIGN KEY(ad_account_id) REFERENCES ad_account (id)
    )
']

My models:我的模特:

from sqlalchemy.dialects.mysql import BIGINT

ad_accounts = db.Table('ad_accounts',
    db.Column('access_token_id', db.Integer, db.ForeignKey('fb_access_token.id')),
    db.Column('ad_account_id', db.Integer, db.ForeignKey('ad_account.id'))
)


class AdAccount(db.Model):
    __bind_key__ = 'ads'
    __tablename__ = 'ad_account'

    id = db.Column(db.Integer, primary_key=True)
    account_id = db.Column(BIGINT(unsigned=True), default=None)
    account_status = db.Column(db.Integer, default=None)
    business_name = db.Column(db.String(255), default='')
    owner = db.Column(db.String(255), default='')
    timezone_name = db.Column(db.String(255), default='')
    created_time = db.Column(db.Integer, default=0)
    activities = db.relationship('Activity', backref='ad_account', lazy='dynamic')


class FbAccessToken(db.Model):
    __bind_key__ = 'ads'
    __tablename__ = 'fb_access_token'

    id            = db.Column(db.Integer, primary_key=True)
    admin_id      = db.Column(db.Integer, db.ForeignKey('admin_user.admin_id'))
    # fb_account_id = db.Column(db.String(32), default='')
    ad_accounts   = db.relationship('AdAccount', secondary=ad_accounts, backref='access_token_list', lazy='dynamic')
    update_time   = db.Column(db.Integer, default=0)
    page_id       = db.Column(BIGINT(unsigned=True), default=0)
    current_account_id = db.Column(BIGINT(unsigned=True), nullable=True)

When every time i was running 'python app.py db upgrade' in product envirment,i was afraid to break it down.每次我在产品环境中运行“python app.py db upgrade”时,我都害怕将其分解。

And someone told me that i should alter table by manual SQL.有人告诉我应该通过手动 SQL 更改表。

I am confused now,i want to do it in a convenient way,i used to do it in django-migration.我现在很困惑,我想以一种方便的方式来做,我以前在 django-migration 中做过。

Suppose I have already created database and tables in product envirment, do I still have to execute create_all or 'python app.py db upgrade'(In Flask-Migrate)?假设我已经在产品环境中创建了数据库和表,我是否还必须执行create_all 或'python app.py db upgrade'(在Flask-Migrate 中)?


And how to add a comment on a column in Flask-Migrate?以及如何在 Flask-Migrate 的列中添加注释?

On an existing database, in production, you obviously don't want to recreate your database schema and lose any existing data.在现有数据库上,在生产中,您显然不希望重新创建数据库模式并丢失任何现有数据。 Look into database migrations , here are the relevant packages:查看数据库迁移,这里是相关的包:

I am not sure if I got well what you want.我不确定我是否得到了你想要的。 I think flask Migrate is a good tool but it have some limitations as stated Here .我认为 flask Migrate 是一个很好的工具,但它有一些限制,如Here所述。

Basically, since alembic doesn't detect every migration you have to edit the migration script by adding foreign keys names when using them as it says in alembic documentation here .基本上,由于 alembic 不会检测到每个迁移,因此您必须在使用它们时通过添加外键名称来编辑迁移脚本,正如此处的 alembic 文档中所述。 I face the same problem with my migration and I resolve it by editing the migration script in folder '/migration/version' by manually adding foreign keys name!我的迁移遇到了同样的问题,我通过手动添加外键名称来编辑文件夹“/migration/version”中的迁移脚本来解决它! with this line of code用这行代码

sa.ForeignKeyConstraint(['access_token_id'], ['fb_access_token.id'],use_alter=True, name='fk_fb_access_token.id_id' ),

or if you don't like to edit migration script you can use the object或者如果您不喜欢编辑迁移脚本,您可以使用该对象

ForeignKeyConstraint

instead of代替

db.ForeignKey()

and give it all the parameter specially name when defining your foreign keys并在定义外键时为所有参数指定名称

But In general, it's because you need to name the foreign keys and don't use the default names但一般来说,这是因为你需要给外键命名,不要使用默认名称

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM