我正在使用MySQL(运行InnoDB),并使用sqlalchemy包装整个事物。现在,我想使用(参见docs)
在我的数据库中生成更改sqlalchemy_utils.functions.create_database(...)
一般来说,上述功能可以实现预期。唯一的例外是生成唯一索引。
说,我定义了一个这样的表:
## ...
# DeclBase = declarative_base()
## ...
class MyTable(DeclBase):
__tablename__ = 'my_table'
id = Column(Integer, primary_key=True)
attr_1 = Column(String(32))
attr_2 = Column(Integer, nullable=False)
attr_3 = Column(DateTime)
attr_4 = Column(
Integer,
ForeignKey('other_table.id', onupdate='CASCADE', ondelete='CASCADE'),
nullable=False
)
u_idx = UniqueConstraint(attr_2, attr_3, 'my_table_uidx')
当我调用create_database时,我将使用sqlalchemy创建表'my_table',其中包含指定的所有列。外键也设置正常,但在数据库端没有找到唯一索引。然后我尝试使用索引(unique = True)。而不是
u_idx = UniqueConstraint(attr_2, attr_3, 'my_table_uidx')
我把
u_idx_1 = Index('my_table_uidx', attr_2, attr_3, unique=True)
我的印象是这在逻辑上产生了类似的结果。这次sqlalchemy确实在db上创建了唯一的索引。
也许我对于UniqueConstraint和Index(unique = True)之间的差异或者sqlalchemy使用它们自动生成数据库的方式产生了误解。
任何人都可以对此有所了解吗?
答案 0 :(得分:2)
主要区别在于,Index
API允许在表定义之外定义索引,只要它可以通过传递的SQL结构引用表,UniqueConstraint
和约束must be defined inline in the table definition 3}}:
要将表
ForeignKeyConstraint
等表级约束对象应用于使用Declarative定义的表,请使用Table Configuration中描述的__table_args__
属性。
要理解的是,在构造声明性类时,如果没有传递明确的Table
,则构造新的__table__
。在示例模型类中,UniqueConstraint
实例绑定到类属性,但声明性基础不包含属性中创建的Table
实例中的约束。您必须在表参数中传递它:
class MyTable(DeclBase):
__tablename__ = 'my_table'
...
# A positional argument tuple, passed to Table constructor
__table_args__ = (
UniqueConstraint(attr_2, attr_3, name='my_table_uidx'),
)
请注意,您必须将约束名称作为关键字参数传递。您也可以使用Table.append_constraint()
传递约束,如果在创建表的任何尝试之前调用了该约束:
class MyTable(DeclBase):
...
MyTable.__table__.append_constraint(
UniqueConstraint('attr_2', 'attr_3', name='my_table_uidx'))