2017-04-07 78 views
1

我正在使用MySQL(運行InnoDB),並使用sqlalchemy包裝了整個事物。現在,我想通過使用產生在我的數據庫的變化(見docsslqlalchemy UniqueConstraint VS Index(unique = True)

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」的規定。外鍵也設置正常,但在數據庫端不能找到唯一的索引。然後,我嘗試使用索引(唯一= 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使用它們來自動生成數據庫。

任何人都可以對此有所瞭解嗎?

回答

2

的主要區別是,雖然Index API允許只要定義一個表定義之外的索引,因爲它可以通過所傳遞的SQL構造引用該表,一個UniqueConstraint和約束一般must be defined inline in the table definition

要將表級約束對象(例如ForeignKeyConstraint)應用於使用聲明性定義的表,使用__table_args__屬性,如Table Configuration所述。

明白的事情是,建設類聲明的過程中一個新的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')) 
+0

很好的解釋!這很有道理。你是否看到任何反對堅持索引('my_table_uidx',attr_2,attr_3,unique = True)的論點?目前我傾向於繼續使用它,因爲它產生了與我以前在MySQL Workbench中手動設置的MySQL定義完全相同的MySQL定義,同時也可以直接在Python一側閱讀。 –

+0

我猜如果使用MySQL,沒有理由選擇其中一個或另一個。不要在此引用我,但是獨特的約束無論如何都被實現爲唯一索引。儘管如此,所有數據庫都可能不是這樣。再一次,我對SQL標準的確定還不夠熟悉。 –

+0

夠公平的。這也是我的直覺。我會發布,如果我遇到任何暗示,否則。謝謝! –