2013-05-09 51 views
0

以下是我在試圖在sqlalchemy中實現多列唯一約束時所做的兩個不同嘗試,兩者似乎都失敗了,因爲沒有正確的SQL語句產生的。SQLAlchemy沒有爲多列生成適當的SQL語句UniqueConstraints

的嘗試:

from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, create_engine, UniqueConstraint, Boolean 
from sqlalchemy.orm import relationship, backref, sessionmaker 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.interfaces import PoolListener 
import sqlalchemy 

class ForeignKeysListener(PoolListener): 
    def connect(self, dbapi_con, con_record): 
     db_cursor = dbapi_con.execute('pragma foreign_keys=ON') 

engine = create_engine(r"sqlite:///" + r"d:\\foo.db", 
         listeners=[ForeignKeysListener()], echo = True) 
Session = sessionmaker(bind = engine) 
ses = Session() 
Base = declarative_base() 
print sqlalchemy.__version__ 
class Foo(Base): 
    __tablename__ = "foo" 

    id = Column(Integer, primary_key=True) 
    dummy = Column(Integer, unique = True) 
class Bar(Base): 
    __tablename__ = "bar" 
    id = Column(Integer, primary_key=True) 
    baz = Column(Integer, ForeignKey("foo.id")) 
    qux = Column(Integer, ForeignKey("foo.id")) 
    UniqueConstraint("baz", "qux") 

class Cruft(Base): 
    __tablename__ = "cruft" 

    id = Column(Integer, primary_key=True) 
    bar = Column(Integer, ForeignKey("foo.id")) 
    qux = Column(Integer, ForeignKey("foo.id")) 
    __table_args = (UniqueConstraint("bar", "qux"),) 
Base.metadata.create_all(engine) 

輸出:

>>> 0.8.2 
2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("foo") 
2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine() 
2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("bar") 
2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine() 
2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("cruft") 
2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine() 
2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE foo (
    id INTEGER NOT NULL, 
    dummy INTEGER, 
    PRIMARY KEY (id), 
    UNIQUE (dummy) 
) 


2013-05-09 16:25:42,677 INFO sqlalchemy.engine.base.Engine() 
2013-05-09 16:25:42,767 INFO sqlalchemy.engine.base.Engine COMMIT 
2013-05-09 16:25:42,769 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE bar (
    id INTEGER NOT NULL, 
    baz INTEGER, 
    qux INTEGER, 
    PRIMARY KEY (id), 
    FOREIGN KEY(baz) REFERENCES foo (id), 
    FOREIGN KEY(qux) REFERENCES foo (id) 
) 


2013-05-09 16:25:42,769 INFO sqlalchemy.engine.base.Engine() 
2013-05-09 16:25:42,838 INFO sqlalchemy.engine.base.Engine COMMIT 
2013-05-09 16:25:42,839 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE cruft (
    id INTEGER NOT NULL, 
    bar INTEGER, 
    qux INTEGER, 
    PRIMARY KEY (id), 
    FOREIGN KEY(bar) REFERENCES foo (id), 
    FOREIGN KEY(qux) REFERENCES foo (id) 
) 


2013-05-09 16:25:42,839 INFO sqlalchemy.engine.base.Engine() 
2013-05-09 16:25:42,917 INFO sqlalchemy.engine.base.Engine COMMIT 

有什麼建議?

回答

2

當在聲明表配置使用UniqueConstraint,你需要使用__table_args__ attribute(注意的名字都兩側的下劃線指定它:

class Bar(Base): 
    __tablename__ = "bar" 
    __table_args__ = (UniqueConstraint("baz", "qux"),) 

    id = Column(Integer, primary_key=True) 
    baz = Column(Integer, ForeignKey("foo.id")) 
    qux = Column(Integer, ForeignKey("foo.id")) 

class Cruft(Base): 
    __tablename__ = "cruft" 
    __table_args__ = (UniqueConstraint("bar", "qux"),) 

    id = Column(Integer, primary_key=True) 
    bar = Column(Integer, ForeignKey("foo.id")) 
    qux = Column(Integer, ForeignKey("foo.id")) 

屬性必須是A 。元組或字典

現在創建這兩個表導致:

2013-05-09 13:38:44,180 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE cruft (
    id INTEGER NOT NULL, 
    bar INTEGER, 
    qux INTEGER, 
    PRIMARY KEY (id), 
    UNIQUE (bar, qux), 
    FOREIGN KEY(bar) REFERENCES foo (id), 
    FOREIGN KEY(qux) REFERENCES foo (id) 
) 

... 

2013-05-09 13:38:44,181 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE bar (
    id INTEGER NOT NULL, 
    baz INTEGER, 
    qux INTEGER, 
    PRIMARY KEY (id), 
    UNIQUE (baz, qux), 
    FOREIGN KEY(baz) REFERENCES foo (id), 
    FOREIGN KEY(qux) REFERENCES foo (id) 
) 

另請參閱Setting up Constraints when using the Declarative ORM Extension section定義約束和索引一章。

+0

忘記添加結尾雙下劃線。修復它解決了問題。謝謝。 – 2013-05-09 11:37:58

+0

在發表評論之後,我很準備,但我得到了類似於「我可以在6分鐘內回答問題」的內容。然後我忘了:P – 2013-05-09 13:13:09

+0

令人困惑的是,[doc](http://docs.sqlalchemy.org/en/latest/core/constraints.html#unique-constraint)並沒有說明它必須在__table_args__變量中。但的確如此,謝謝。 – Zitrax 2016-11-03 21:25:55