Alembic 不从 SQLAlchemy 类自动生成表

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

sqlalchemy:2.0.25 蒸馏器:1.13.1 蟒蛇:3.11

alembic revision --autogenerate -m "initial migration"
在迁移中创建空的
upgrade
downgrade
代码。

如下所示,我在与基类不同的文件中有两个模型类。

我的 alembic/env.py 按照他们的文档说明导入我的基类,以便它可以访问元数据。在空数据库上,这应该会生成升级代码来创建 Order 和 Item 表,但似乎没有从 Base.metadata 中找到这些类。 1. 凭直觉,我将这些类的导入放入 env.py 中(如下所示),然后正确地自动生成迁移。 2. 作为一种替代解决方法,我还发现将所有模型与 Base 一起放入一个大文件中可以完整生成。

解决方法 1 还可以,但随着模型类数量的增加,会有点麻烦。解决方法 2 是不可接受的。

是否有更优雅和可靠的方法让它找到所有模型类以进行自动生成?

#models.base.py

from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
    pass

#models.order.py

from models.base import Base

class Order(Base):
    __tablename__ = "Order"

    id: Mapped[int] = mapped_column(primary_key=True)
    description: Mapped[Optional[str]]
    items: Mapped[List["Item"]] = relationship(back_populates="order")
 
#models.item.py

from models.base import Base

class Item(Base):
    __tablename__ = "Item"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    description: Mapped[str] = mapped_column(String(255))

    order_id: Mapped[int] = mapped_column(ForeignKey("Order.id"))
    order: Mapped["Order"] = relationship(back_populates="items")
 
 

#alembic/env.py  (excerpt)
from models.base import Base
from models.order import Order # not prescribed by doc but makes it work
from models.item import Item # same as above
target_metadata = Base.metadata
 
 
sqlalchemy migration alembic
1个回答
0
投票

您可以在单独的文件中定义基类,例如

base_class.py
,在模型定义中重用它,例如
order.py
并将所有模型导入到
base.py
文件中以在 alembic
env.py
中使用。

例如

# db.base_class.py

from typing import Any
from sqlalchemy.ext.declarative import as_declarative, declared_attr

@as_declarative()
class Base:
    id: Any
    __name__: str
    
    # Generate __tablename__ automatically
    @declared_attr
    def __tablename__(cls) -> str:
        return cls.__name__.lower()

# models.order.py

from db.base_class import Base

class Order(Base):
    id: Mapped[int] = mapped_column(primary_key=True)
    description: Mapped[Optional[str]]
    items: Mapped[List["Item"]] = relationship(back_populates="order")

# models.base.py

from db.base_class import Base # noqa
from models.order import Order # noqa
from models.item import Item   # noqa

如果创建迁移脚本时出现错误,可以在模型的init.py中导入模型

# models.__init__.py

from .order import Order # noqa
from .item import Item   # noqa

有了这个,您不必每次创建模型时都更新 alembic.env.py,但您必须在

models.base.py
中导入它,以及 Order 和 Item。

© www.soinside.com 2019 - 2024. All rights reserved.