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

Анд*_*кий 6 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))
Run Code Online (Sandbox Code Playgroud)

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

from sqlalchemy_utils.types.choice import ChoiceType
Run Code Online (Sandbox Code Playgroud)

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

context.configure(
    connection=connection,
    target_metadata=target_metadata,
    user_module_prefix="mytypes.types."
    # ...
)
Run Code Online (Sandbox Code Playgroud)

, 在 script.py.mako 中

import mytypes.types
Run Code Online (Sandbox Code Playgroud)

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

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 ###
Run Code Online (Sandbox Code Playgroud)

为什么 alembic 没有将“LEVEL”参数传递给choicetype,为什么它传递了 length=255 呢?

Joh*_*ord 7

我已经为这个问题提出了一个更自动化的解决方案。在我的 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


Run Code Online (Sandbox Code Playgroud)

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

   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,
        )
Run Code Online (Sandbox Code Playgroud)

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


小智 5

我通过手动将其更改mytypes.types.ChoiceType(length=255)mytypes.types.ChoiceType(MyEnum) 并导入来 修复 它。


小智 0

Alembic 和 SqlAlchemy-utils 并不像我们想象的那样是朋友。因此,请将模型文件导入到 alembic 迁移版本文件中,并相应地编辑升级功能。

就像这里完成的那样https://sqlalchemy-utils.readthedocs.io/en/latest/data_types.html#module-sqlalchemy_utils.types.choice