2

以下は、sqlalchemy で複数列の一意の制約を達成しようとして行った 2 つの異なる試みです。適切な 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

助言がありますか?

4

1 に答える 1

4

宣言的なテーブル構成で aを使用する場合は、属性UniqueConstraintを使用して指定する必要があります (名前の両側にある下線に注意してください。__table_args__

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 つのテーブルを作成すると、次のようになります。

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

制約とインデックスの定義の章の宣言型 ORM 拡張を使用する場合の制約の設定セクションも参照してください。

于 2013-05-09T11:33:25.190 に答える