2013-05-09 3 views
0

다음은 SQL 문에서 다중 열 고유 제한 조건을 달성하기 위해 시도한 두 가지 시도입니다. 둘 다 올바른 SQL 문이 작성되지 않았기 때문에 실패한 것으로 보입니다 생산.SQLAlchemy가 다중 열 UniqueConstraints에 대한 적절한 SQL 문을 생성하지 않음

시도 :

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 

어떤 제안이?

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")) 

중 하나 여야합니다 속성 :

답변

2

선언 테이블 구성에 UniqueConstraint를 사용하여, 당신은 __table_args__ attribute가 (이름의 모두 측면에 밑줄을 유의 사용하여 지정해야 .

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

끝나는 두 줄 밑줄을 추가하지 마십시오. 그것을 고치면 문제가 해결되었습니다. 감사. –

+0

내가 의견을 말한 직후에 갈 것이지만 "나는 6 분 안에 질문에 대답 할 수 있습니다."와 비슷한 것을 얻었습니다. 그리고 나서 나는 잊었다 : P –

+0

그것은 혼란 스러웠다. [doc] (http://docs.sqlalchemy.org/en/latest/core/constraints.html#unique-constraint)는이 사실을 분명히하지 않았다. __table_args__ 변수에 있어야합니다. 하지만 실제로 작동합니다. – Zitrax