/ / SQLAlchemy ne produisant pas d'instruction SQL appropriée pour les colonnes uniques UniqueConstraints - python, sql, sqlalchemy, unique-contrainte

SQLAlchemy ne produisant pas d'instruction SQL appropriée pour les colonnes uniques UniqueConstraints - python, SQL, sqlalchemy, unique-contrainte

Ci-dessous les deux tentatives différentes que j'ai faitesen essayant d'obtenir une contrainte unique multi-colonnes dans sqlalchemy, les deux semblent avoir échoué car aucune instruction SQL adéquate n'est générée.

Les tentatives:

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)

Le résultat:

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

Aucune suggestion?

Réponses:

2 pour la réponse № 1

Lorsque vous utilisez un UniqueConstraint dans une configuration de table déclarative, vous devez le spécifier en utilisant le __table_args__ attribut (notez les soulignés sur tous les deux côtés du nom:

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

L'attribut doit soit un tuple ou un dictionnaire.

La création de ces deux tables a maintenant pour résultat:

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

Voir aussi le Configuration de contraintes lors de l'utilisation de l'extension ORM déclaratif section du Définir des contraintes et des index chapitre.