SQLAlchemy 使用 naming_convention 创建多列索引

SQLAlchemy create multi column index using naming_convention

我正在尝试为基于 table 的模型创建多(即 2 列索引)。但我不想为该索引指定具体名称。我希望 naming_conventionalembic revision --autogenerate 能够完成命名索引的工作。到目前为止,我有这样的代码:

from sqlalchemy import MetaData
from sqlalchemy.ext.declarative import as_declarative
from sqlalchemy.schema import Index

metadata = MetaData(
        naming_convention={
            'pk': '%(table_name)s_pk',
            'ix': '%(table_name)s_%(column_0_N_name)s_ix',
        },
    )

@as_declarative(metadata=metadata)
class Base:
    pass

class Foo(Base):
    id = Column(Integer, primary_key=True)
    col1 = Column('Col1', Integer)
    col2 = Column('Col2', DateTime)

Index(
    metadata.naming_convention['ix'] % {
        'table_name': Foo.__tablename__,
        'column_0_N_name': Foo.col1.expression.name + "_" + Foo.col2.expression.name
    },
    Foo.col1,
    Foo.col2,
)

所以我想避免代码的 'creating name' 部分:

    metadata.naming_convention['ix'] % {
        'table_name': Foo.__tablename__,
        'column_0_N_name': Foo.col1.expression.name + "_" + Foo.col2.expression.name
    }

经过更多的搜索,有一个非常简单的解决方案。根据 github comment in SQLAlchemy issue,如果您想通过 Index() 创建索引,您只需传递 name=None 参数,并为列填充参数。

所以上面的代码应该看起来像(保持不变的部分):

from sqlalchemy import MetaData
from sqlalchemy.ext.declarative import as_declarative
from sqlalchemy.schema import Index

metadata = MetaData(
        naming_convention={
            'pk': '%(table_name)s_pk',
            'ix': '%(table_name)s_%(column_0_N_name)s_ix',
        },
    )

@as_declarative(metadata=metadata)
class Base:
    pass

选项 1(在 table 模型中声明多列索引)

class Foo(Base):
    id = Column(Integer, primary_key=True)
    col1 = Column('Col1', Integer)
    col2 = Column('Col2', DateTime)

Index(None, Foo.col1, Foo.col2)

选项 2(在 table 模型中声明多列索引)

class Foo(Base):
    id = Column(Integer, primary_key=True)
    col1 = Column('Col1', Integer)
    col2 = Column('Col2', DateTime)
    __table_args__ = (
        Index(None, 'Col1', 'Col2'),
    )

那么索引名称(在两个选项中)将是:

Foo_Col1_Col2_ix

我没有在 SQLALchemy 文档中找到这种解决方案(也许有?),但是在 SQLAlchemy github 中有一些关于 github 问题的答案很好 github :)