Python SLQLachemy UniqueConstraint VS Index(唯一=真)

Python SLQLachemy UniqueConstraint VS Index(唯一=真),python,mysql,database,sqlalchemy,Python,Mysql,Database,Sqlalchemy,我正在使用MySQL(运行InnoDB),并使用sqlalchemy包装了整个内容。现在,我想使用(请参阅)在数据库中生成更改 通常,上述函数执行它应该执行的操作。唯一的例外是生成唯一索引 比如说,我定义了这样一个表: ## ... # DeclBase = declarative_base() ## ... class MyTable(DeclBase): __tablename__ = 'my_table' id = Column(Integer, primary_key=

我正在使用MySQL(运行InnoDB),并使用sqlalchemy包装了整个内容。现在,我想使用(请参阅)在数据库中生成更改

通常,上述函数执行它应该执行的操作。唯一的例外是生成唯一索引

比如说,我定义了这样一个表:

## ...
# 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')
我把

我的印象是,这在逻辑上产生了类似的结果。这次sqlalchemy确实在db上创建了唯一的索引

也许我对UniqueConstraint和Index(unique=True)之间的区别,或者对sqlalchemy使用它们自动生成数据库的方式,有着严重的误解


有人能解释一下这一点吗?

主要区别在于,虽然允许在表定义之外定义索引,但只要它可以通过传递的SQL构造引用表,通常情况下,a和约束:

要将表级约束对象(如
ForeignKeyConstraint
)应用于使用声明性定义的表,请使用
\uuuu table\u args\uuuu
属性,如中所述

需要理解的是,在构造声明性类的过程中,如果没有传递显式的
\uuuuu Table\uuu
,就会构造一个新的
表。在您的示例模型类中,
UniqueConstraint
实例绑定到一个class属性,但是声明性基在创建的
实例属性中不包含约束。必须在表参数中传递它:

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'),
    )
请注意,必须将约束名称作为关键字参数传递。如果在尝试创建表之前调用,还可以使用以下命令传递约束:

class MyTable(DeclBase):
    ...

MyTable.__table__.append_constraint(
    UniqueConstraint('attr_2', 'attr_3', name='my_table_uidx'))

很好的解释!这很有道理。您是否看到反对坚持使用索引('my_table_uidx',attr_2,attr_3,unique=True)实现的任何论据?目前我倾向于使用它,因为它生成的MySQL定义与我之前在MySQL Workbench中手动设置的完全相同,同时也可以直接在python端阅读。如果使用MySQL,我想没有理由选择其中之一。请不要引用我的话,但唯一约束无论如何都是作为唯一索引实现的。不过,并非所有数据库都是如此。同样,我对SQL标准还不够熟悉,不能肯定,这很公平。这也是我的直觉。如果我遇到任何与此相反的建议,我会发帖。谢谢
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'),
    )
class MyTable(DeclBase):
    ...

MyTable.__table__.append_constraint(
    UniqueConstraint('attr_2', 'attr_3', name='my_table_uidx'))