python - 将 alembic 与 sqlalchemy_utils 一起使用时出现问题

标签 python sqlalchemy alembic

在我的 sqlalchemy 模型中,我使用 sqlalchemy_utils 的选择类型:

id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.Integer, nullable=True)
level = db.Column(mytypes.types.ChoiceType(LEVEL))

我按照这里描述的做了所有事情http://alembic.readthedocs.org/en/latest/autogenerate.html#autogen-module-prefix .在我的模型中,我从我的模块 mytypes.types 中导入了 choicetype:

from sqlalchemy_utils.types.choice import ChoiceType

,在 alembic/env.py 中我添加了上下文

context.configure(
    connection=connection,
    target_metadata=target_metadata,
    user_module_prefix="mytypes.types."
    # ...
)

,并在 script.py.mako 中

import mytypes.types

.问题是当我修改我的模型时,我得到了一些东西
像这样

from alembic import op
import sqlalchemy as sa
import mytypes.types

def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('logging', sa.Column('level', mytypes.types.ChoiceType(length=255), nullable=True))
### end Alembic commands ###

为什么 alembic 没有将“LEVEL”参数传递给 choicetype 而传递的是 length=255?

最佳答案

针对这个问题,我想出了一个更自动化的解决方案。在我的 env.py 函数 run_migrations_online() 中,我添加了一个处理 sqlalchemy_utils 类型的自定义渲染器。我只测试了 ChoiceType 和 UUIDType,但它们对我有用。

所以在 env.py 和自定义渲染函数中:

  def render_item(type_, obj, autogen_context):
        """Apply custom rendering for selected items."""

        if type_ == "type" and obj.__class__.__module__.startswith("sqlalchemy_utils."):
            autogen_context.imports.add(f"import {obj.__class__.__module__}")
            if hasattr(obj, "choices"):
                return f"{obj.__class__.__module__}.{obj.__class__.__name__}(choices={obj.choices})"
            else:
                return f"{obj.__class__.__module__}.{obj.__class__.__name__}()"

        # default rendering for other objects
        return False


然后我修改了现有的上下文配置以使用它:

   with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata,
            render_item=render_item,
            process_revision_directives=process_revision_directives,
            **current_app.extensions["migrate"].configure_args,
        )

这意味着当我使用新的 sqlalchemy_utils 运行 manage.py db migrate 时,它会正确导入模块并将类型添加到迁移中。我为 ChoiceType 的选择属性添加了特殊处理。这可能需要针对更多类型/属性进行扩展。

关于python - 将 alembic 与 sqlalchemy_utils 一起使用时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30132370/

相关文章:

python - 让 Flask-Migrate 忽略映射为 Flask-SQLAlchemy 模型的 SQL View

python - 根据条件选择最后一行并将值存储到变量中

python - BeautifulSoup 抓取文本

python - Alembic:如何迁移模型中的自定义类型?

python - 插入是否最优?

python - 如何使用 mysqlconnector 在 SQLAlchemy 中设置 FOUND_ROWS 的 client_flags 以返回受影响的行

python - 如何以编程方式运行/调用 Flask cli 命令?

python - 在进程池中共享数据库连接

python - 如何在HBase中关闭WAL,

python - LOAD DATA LOCAL INFILE sqlalchemy 和 python 到 mysql 数据库