【问题标题】:In Flask-SQLAlchemy, Should i use create_all() to create tables in production environment?在 Flask-SQLAlchemy 中,我应该使用 create_all() 在生产环境中创建表吗?
【发布时间】:2021-05-17 21:52:47
【问题描述】:

我是 Flask 的新手。 我正在研究 Flask-SQLAlchemy,我也尝试过 Flask-Migrate。

快速创建生产和测试环境非常方便。

但我认为它不如 Django-Migration 方便。

当我尝试创建 多对多 数据模型时。 我有时会收到以下错误:

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)
    )
']

我的模型:

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)

当我每次在产品环境中运行'python app.py db upgrade'时,我都害怕打破它。

有人告诉我应该通过手动 SQL 更改表。

我现在很困惑,我想以一种方便的方式来做,我曾经在 django-migration 中做。

假设我已经在产品环境中创建了数据库和表,是否还需要执行 create_all 或 'python app.py db upgrade'(In Flask-Migrate)?


以及如何在 Flask-Migrate 中的列上添加评论?

【问题讨论】:

    标签: python flask flask-sqlalchemy


    【解决方案1】:

    在现有数据库上,在生产环境中,您显然不想重新创建数据库架构并丢失任何现有数据。查看数据库迁移,这里是相关的包:

    【讨论】:

    • 我应该使用 Flask-Migrate 吗?
    【解决方案2】:

    我不确定我是否得到了你想要的。 我认为flask Migrate 是一个很好的工具,但正如Here 所述,它有一些限制。

    基本上,由于 alembic 不会检测到每个迁移,因此您必须通过在使用外键名称时添加外键名称来编辑迁移脚本,正如 alembic 文档 here 中所述 . 我的迁移遇到了同样的问题,我通过手动添加外键名称来编辑文件夹“/migration/version”中的迁移脚本来解决它!用这行代码

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

    或者如果您不喜欢编辑迁移脚本,您可以使用该对象

    ForeignKeyConstraint
    

    而不是

    db.ForeignKey()
    

    并在定义外键时为所有参数指定名称

    但总的来说,这是因为您需要命名外键并且不要使用默认名称

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-11
      相关资源
      最近更新 更多