Ignoring a model when using alembic autogenerate

浪子不回头ぞ 提交于 2021-02-10 05:21:46

问题


I am trying to autogenerate revisions for my DB using alembic. While doing so, I want to ignore some models (they have data types that are not supported by current version of MySQL). Here is what I tried and it seems to work fine, but I am not sure that's the most idiomatic way of doing it

inside alembic/env.py

def include_object(object, type_, name, reflected, compare_to):
    if type_ == 'table' and name == 'model_to_be_ignored':
        return False
    return True

and then inside run_migrations_online and run_migrations_offline I gave include_object=include_object and this seems to be working fine.

Ideally I would like to use skip_autogenerate=True, but not sure I can define that, so that later on I can simply remove that line in the models.py and get my desired behavior when I upgrade to newer version of database.

Is there something I am missing?


回答1:


As far as I can see, skip_autogenerate is not automatically handled by Alembic nor SQLAlchemy. But you can add it to Table.info like this:

  1. Define a mixin that adds skip_autogenerate to Table.info. This is based in Flask-SQLAlchemy's BindMetaMixin
class ModelInfoMetaMixin(object):
    def __init__(cls, name, bases, d):
        skip_autogenerate = d.pop("__skip_autogenerate__", None)

        super(ModelInfoMetaMixin, cls).__init__(name, bases, d)

        if skip_autogenerate is not None and getattr(cls, "__table__", None) is not None:
            cls.__table__.info["skip_autogenerate"] = skip_autogenerate
  1. Use this mixin to define a meta class and pass it to declarative_base()
from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base

class DefaultMeta(ModelInfoMetaMixin, DeclarativeMeta):
    pass

Model = declarative_base(cls=BaseModel, metaclass=DefaultMeta)
  1. Then you can define your models with this marker:
class OneModel(Model):
    __skip_autogenerate__ = True
    uuid = Column(UUID(as_uuid=True), primary_key=True)
  1. Finally, skip_autogenerate will be available in Alembic's include_object:
def include_object(object, name, type_, reflected, compare_to):
    # skip objects marked with "skip_autogenerate"
    if object.info.get("skip_autogenerate", False):
        return False

    return True


来源:https://stackoverflow.com/questions/54978681/ignoring-a-model-when-using-alembic-autogenerate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!