postgresql 烧瓶迁移和更改列类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33944436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 02:05:58  来源:igfitidea点击:

Flask-migrate and changing column type

postgresqlpython-3.xflaskalembic

提问by Thustra

I am trying to learn some Flask and I am using Flask-Migrate 1.6.0

我正在尝试学习一些 Flask 并且我正在使用 Flask-Migrate 1.6.0

So I made a model which looks like this

所以我做了一个看起来像这样的模型

class Download(db.Model):

    __tablename__ = "downloads"

    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    filename = db.Column(db.String, nullable=False)
    size = db.Column(db.Integer, nullable=False)
    location = db.Column(db.String, nullable=False)
    season = db.Column(db.Integer, nullable=False)
    download_timestamp = db.Column(db.DateTime, nullable=False)

    show_id = db.Column(db.Integer, ForeignKey("shows.id"))

    def __init__(self,filename,size,location,timestamp,season):
        self.filename = filename
        self.size = size
        self.location = location
        self.download_timestamp = timestamp
        self.season = season

    def __repr__(self):
        return '<File {}'.format(self.filename)

I have then changed it to the exact same thing except for this line :

然后我将它更改为完全相同的内容,除了这一行:

size = db.Column(db.BigInteger, nullable=False)

When I run my

当我运行我的

manager.py db migrate

command it doesn't detect the change in the column type. And I have read up on it and I know it should pick it up when I change my env.py and add the compare_type=True variable. But I did this to no avail, the method looks like this right now

命令它不检测列类型的变化。我已经阅读了它,我知道当我更改 env.py 并添加 compare_type=True 变量时它应该会选择它。但我这样做无济于事,方法现在看起来像这样

def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """

    # this callback is used to prevent an auto-migration from being generated
    # when there are no changes to the schema
    # reference: http://alembic.readthedocs.org/en/latest/cookbook.html
    def process_revision_directives(context, revision, directives):
        if getattr(config.cmd_opts, 'autogenerate', False):
            script = directives[0]
            if script.upgrade_ops.is_empty():
                directives[:] = []
                logger.info('No changes in schema detected.')

    engine = engine_from_config(config.get_section(config.config_ini_section),
                                prefix='sqlalchemy.',
                                poolclass=pool.NullPool)

    connection = engine.connect()
    context.configure(connection=connection,
                      target_metadata=target_metadata,
                      compare_type=True,
                      process_revision_directives=process_revision_directives,
                      **current_app.extensions['migrate'].configure_args)

    try:
        with context.begin_transaction():
            context.run_migrations()
    finally:
        connection.close()

Ok so my questions are:

好的,所以我的问题是:

Did I do something wrong in changing the env.py file?

我在更改 env.py 文件时做错了什么吗?

If I didn't and it still doesn't pick up on it how do I exactly manually make the next migration revision? Because the revisions in my migrate folder have names like below and stuff in it like this

如果我没有并且它仍然没有接受它,我该如何手动进行下一次迁移修订?因为我的 migrate 文件夹中的修订具有如下名称和这样的内容

# revision identifiers, used by Alembic.
revision = '7e9f264b0f'
down_revision = '2e59d536f50'

I guess I could just copy one, make up a name .. but would the next one that is picked up by flask migrate recognize it? So yeah.. what is the correct way of handling it without too much iffy hacking?

我想我可以只复制一个,起个名字..但是flask migrate接收到的下一个会识别它吗?所以是的......没有太多可疑的黑客攻击的正确处理方法是什么?

回答by enpi

Just need to add compare_type=True in the Migrate constructor

只需要在 Migrate 构造函数中添加 compare_type=True

from flask_migrate import Migrate
migrate = Migrate(compare_type=True)

app = Flask(__name__)
migrate.init_app(app)

回答by KageUrufu

Update:

更新:

As expected, this answer is now out of date, please see https://stackoverflow.com/a/52181159/428907for a real fix!

正如预期的那样,这个答案现在已经过时了,请参阅https://stackoverflow.com/a/52181159/428907以获得真正的修复!

Original Answer:

原答案:

Alembic does not recognize things like column type changes when auto-generating revisions by default. When making these more granular changes, you will need to hand-modify the migration to include these changes

默认情况下,Alembic 在自动生成修订时无法识别列类型更改等内容。在进行这些更精细的更改时,您需要手动修改迁移以包含这些更改

e.g., in your migration file

例如,在您的迁移文件中

from alembic import op
import sqlalchemy as sa
def upgrade():
    # ...
    op.alter_column('downloads', 'size', existing_type=sa.Integer(), type_=sa.BigInteger())
def downgrade():
    # ...
    op.alter_column('downloads', 'size', existing_type=sa.BigInteger(), type_=sa.Integer())

For details on the operations, see the operation reference

具体操作见操作参考

You can turn on detection of type changes by modifying your env.py and alembic.ini, as seen here

您可以通过修改您的env.py和alembic.ini打开检测方式的变化,看到这里

回答by Suyash Soni

By default, Flask-migrate doesn't track the changes when type of column is changed. One of many ways to achieve this is to set

默认情况下,Flask-migrate 不会在列类型更改时跟踪更改。实现这一目标的众多方法之一是设置

compare_type=True

比较类型=真

Under env.py. e.g. -

env.py 下。例如——

context.configure(connection=connection,
                      target_metadata=target_metadata,
                      process_revision_directives=process_revision_directives,
                      compare_type=True,
                      **current_app.extensions['migrate'].configure_args)

回答by Savad KP

Tha flask-migratedidn't detect the Columnchanges most of the time. If you delete the sizefield then flask-migratewill detect the change. Then run

大多数情况下,Thaflask-migrate没有检测到这些Column变化。如果您删除该size字段,flask-migrate则将检测到更改。然后运行

manager.py db migrate

manager.py db migrate

Then add sizefiled

然后添加size归档

size = db.Column(db.BigInteger, nullable=False)and migrate.

size = db.Column(db.BigInteger, nullable=False)和迁移。

回答by Luigi Lopez

I have created a script for an automated way to add the compare_type=true in Flask, feel free to used and improve it.

我已经为在 Flask 中添加 compare_type=true 的自动化方式创建了一个脚本,请随意使用和改进它。

make dbinit
sudo sed -i '75i\                      compare_type=True,' env.py
make dbmigrate
make dbupgadre

Cheers,

干杯,