告诉 Flask-Migrate / Alembic 不要删除任何它不知道的表

问题描述 投票:0回答:3

我有一个数据库,其中包含我的 Python 代码未使用的现有表。我使用 Flask-Migrate 生成了一个迁移并运行它,它在创建用户表时删除了我现有的表。如何在不删除任何现有表的情况下运行迁移?

我阅读了“在运行 Flask-Migrate 时保留数据库中的现有表”这个问题的答案,但它对我不起作用,因为我不拥有数据库,而且我不知道哪些表可能存在于部署时间...这意味着我无法将应保留的表列入白名单.

有没有办法告诉 Flask-migrate/Alembic 不要删除它不知道的任何表?

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'my_data'

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

manager = Manager(app)
manager.add_command('db', MigrateCommand)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))

if __name__ == '__main__':
    manager.run()
python flask alembic
3个回答
3
投票

你只需要这个:

# in env.py

def include_object(object, name, type_, reflected, compare_to):
    if type_ == "table" and reflected and compare_to is None:
        return False
    else:
        return True


context.configure(
    # ...
    include_object = include_object

在此处查看文档:https://alembic.sqlalchemy.org/en/latest/cookbook.html#don-t-generate-any-drop-table-directives-with-autogenerate


0
投票

您可以使用

Rewriter
并在删除前进行自动检查。 覆盖
ops.DropTableOp
操作。

如果你愿意,你也可以输入一个条款来只删除你能控制的表。这些将是从您的

Base
(如果是纯蒸馏器)或
db.Model
(对于烧瓶)继承的。

例子

from alembic.autogenerate import rewriter
from alembic.operations import ops

writer = rewriter.Rewriter()

@writer.rewrites(ops.DropTableOp)
def add_column(context, revision, op):
    if op.table_name in Base.metadata.tables.keys():  
        return op  # only return an operation when you want
    return []  # we need to return an iterable

请注意,在

writer
文件中执行
process_revision_directives
时,需要将
context.configure
对象传递给
env.py
kwarg。 (见文档)


0
投票

migrations/env.py
文件中,添加这个函数:

def include_object(object, name, type_, reflected, compare_to):
    if type_ == "table" and reflected and compare_to is None:
        return False
    else:
        return Tru

并修改

run_migrations_online
函数:

def run_migrations_online():
    ...
    with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata,
            process_revision_directives=process_revision_directives,
            # new line
            include_object=include_object,
            **current_app.extensions['migrate'].configure_args)
    ...
© www.soinside.com 2019 - 2024. All rights reserved.