SQLAlchemy 使用 naming_convention 创建多列索引
SQLAlchemy create multi column index using naming_convention
我正在尝试为基于 table 的模型创建多(即 2 列索引)。但我不想为该索引指定具体名称。我希望 naming_convention
和 alembic 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 :)
我正在尝试为基于 table 的模型创建多(即 2 列索引)。但我不想为该索引指定具体名称。我希望 naming_convention
和 alembic 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 :)