"verbose",
}
+FK_ON_DELETE = re.compile(
+ r"^(?:RESTRICT|CASCADE|SET (?:NULL|DEFAULT)(?:\s*\(.+\))?|NO ACTION)$",
+ re.I,
+)
+
colspecs = {
sqltypes.ARRAY: _array.ARRAY,
sqltypes.Interval: INTERVAL,
text += self._define_constraint_validity(constraint)
return text
+ def define_constraint_ondelete_cascade(self, constraint):
+ return " ON DELETE %s" % self.preparer.validate_sql_phrase(
+ constraint.ondelete, FK_ON_DELETE
+ )
+
def visit_create_enum_type(self, create, **kw):
type_ = create.element
r"[\s]?(ON UPDATE "
r"(CASCADE|RESTRICT|NO ACTION|SET NULL|SET DEFAULT)+)?"
r"[\s]?(ON DELETE "
- r"(CASCADE|RESTRICT|NO ACTION|SET NULL|SET DEFAULT)+)?"
+ r"(CASCADE|RESTRICT|NO ACTION|"
+ r"SET (?:NULL|DEFAULT)(?:\s\(.+\))?)+)?"
r"[\s]?(DEFERRABLE|NOT DEFERRABLE)?"
r"[\s]?(INITIALLY (DEFERRED|IMMEDIATE)+)?"
)
def define_constraint_cascades(self, constraint):
text = ""
if constraint.ondelete is not None:
- text += " ON DELETE %s" % self.preparer.validate_sql_phrase(
- constraint.ondelete, FK_ON_DELETE
- )
+ text += self.define_constraint_ondelete_cascade(constraint)
+
if constraint.onupdate is not None:
- text += " ON UPDATE %s" % self.preparer.validate_sql_phrase(
- constraint.onupdate, FK_ON_UPDATE
- )
+ text += self.define_constraint_onupdate_cascade(constraint)
return text
+ def define_constraint_ondelete_cascade(self, constraint):
+ return " ON DELETE %s" % self.preparer.validate_sql_phrase(
+ constraint.ondelete, FK_ON_DELETE
+ )
+
+ def define_constraint_onupdate_cascade(self, constraint):
+ return " ON UPDATE %s" % self.preparer.validate_sql_phrase(
+ constraint.onupdate, FK_ON_UPDATE
+ )
+
def define_constraint_deferrability(self, constraint):
text = ""
if constraint.deferrable is not None:
")",
)
+ def test_create_foreign_key_constraint_ondelete_column_list(self):
+ m = MetaData()
+ pktable = Table(
+ "pktable",
+ m,
+ Column("tid", Integer, primary_key=True),
+ Column("id", Integer, primary_key=True),
+ )
+ fktable = Table(
+ "fktable",
+ m,
+ Column("tid", Integer),
+ Column("id", Integer),
+ Column("fk_id_del_set_null", Integer),
+ Column("fk_id_del_set_default", Integer, server_default=text("0")),
+ ForeignKeyConstraint(
+ columns=["tid", "fk_id_del_set_null"],
+ refcolumns=[pktable.c.tid, pktable.c.id],
+ ondelete="SET NULL (fk_id_del_set_null)",
+ ),
+ ForeignKeyConstraint(
+ columns=["tid", "fk_id_del_set_default"],
+ refcolumns=[pktable.c.tid, pktable.c.id],
+ ondelete="SET DEFAULT(fk_id_del_set_default)",
+ ),
+ )
+
+ self.assert_compile(
+ schema.CreateTable(fktable),
+ "CREATE TABLE fktable ("
+ "tid INTEGER, id INTEGER, "
+ "fk_id_del_set_null INTEGER, "
+ "fk_id_del_set_default INTEGER DEFAULT 0, "
+ "FOREIGN KEY(tid, fk_id_del_set_null)"
+ " REFERENCES pktable (tid, id)"
+ " ON DELETE SET NULL (fk_id_del_set_null), "
+ "FOREIGN KEY(tid, fk_id_del_set_default)"
+ " REFERENCES pktable (tid, id)"
+ " ON DELETE SET DEFAULT(fk_id_del_set_default)"
+ ")",
+ )
+
def test_exclude_constraint_min(self):
m = MetaData()
tbl = Table("testtbl", m, Column("room", Integer, primary_key=True))
from sqlalchemy import Column
from sqlalchemy import exc
from sqlalchemy import ForeignKey
+from sqlalchemy import ForeignKeyConstraint
from sqlalchemy import Identity
from sqlalchemy import Index
from sqlalchemy import inspect
from sqlalchemy import Table
from sqlalchemy import testing
from sqlalchemy import Text
+from sqlalchemy import text
from sqlalchemy import UniqueConstraint
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.dialects.postgresql import base as postgresql
subject = Table("subject", meta2, autoload_with=connection)
eq_(subject.primary_key.columns.keys(), ["p2", "p1"])
+ def test_reflected_foreign_key_ondelete_column_list(
+ self, metadata, connection
+ ):
+ meta1 = metadata
+ pktable = Table(
+ "pktable",
+ meta1,
+ Column("tid", Integer, primary_key=True),
+ Column("id", Integer, primary_key=True),
+ )
+ Table(
+ "fktable",
+ meta1,
+ Column("tid", Integer),
+ Column("id", Integer),
+ Column("fk_id_del_set_null", Integer),
+ Column("fk_id_del_set_default", Integer, server_default=text("0")),
+ ForeignKeyConstraint(
+ columns=["tid", "fk_id_del_set_null"],
+ refcolumns=[pktable.c.tid, pktable.c.id],
+ ondelete="SET NULL (fk_id_del_set_null)",
+ ),
+ ForeignKeyConstraint(
+ columns=["tid", "fk_id_del_set_default"],
+ refcolumns=[pktable.c.tid, pktable.c.id],
+ ondelete="SET DEFAULT(fk_id_del_set_default)",
+ ),
+ )
+
+ meta1.create_all(connection)
+ meta2 = MetaData()
+ fktable = Table("fktable", meta2, autoload_with=connection)
+ fkey_set_null = next(
+ c
+ for c in fktable.foreign_key_constraints
+ if c.name == "fktable_tid_fk_id_del_set_null_fkey"
+ )
+ eq_(fkey_set_null.ondelete, "SET NULL (fk_id_del_set_null)")
+ fkey_set_default = next(
+ c
+ for c in fktable.foreign_key_constraints
+ if c.name == "fktable_tid_fk_id_del_set_default_fkey"
+ )
+ eq_(fkey_set_default.ondelete, "SET DEFAULT (fk_id_del_set_default)")
+
def test_pg_weirdchar_reflection(self, metadata, connection):
meta1 = metadata
subject = Table(