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