`PostgreSQL CREATE TABLE options
<https://www.postgresql.org/docs/current/static/sql-createtable.html>`_
+.. _postgresql_constraint_options:
+
+PostgreSQL Constraint Options
+-----------------------------
+
+* ``NOT VALID``::
+
+ CheckConstraint("some_field IS NOT NULL", postgresql_not_valid=True)
+
+ ForeignKeyConstraint(["some_id"], ["some_table.some_id"], postgresql_not_valid=True)
+
+ The above option is only available on check and foreign key constraints.
+
+ .. seealso::
+
+ `PostgreSQL ALTER TABLE options
+ <https://www.postgresql.org/docs/current/static/sql-altertable.html>`_
+
.. _postgresql_table_valued_overview:
Table values, Table and Column valued functions, Row and Tuple objects
colspec += " NULL"
return colspec
+ def _define_constraint_validity(self, constraint):
+ if self.dialect._supports_not_valid_constraints:
+ not_valid = constraint.dialect_options["postgresql"]["not_valid"]
+ if not_valid:
+ return " NOT VALID"
+
+ return ""
+
def visit_check_constraint(self, constraint):
if constraint._type_bound:
typ = list(constraint.columns)[0].type
"create_constraint=False on this Enum datatype."
)
- return super(PGDDLCompiler, self).visit_check_constraint(constraint)
+ text = super(PGDDLCompiler, self).visit_check_constraint(constraint)
+ text += self._define_constraint_validity(constraint)
+ return text
+
+ def visit_foreign_key_constraint(self, constraint):
+ text = super(PGDDLCompiler, self).visit_foreign_key_constraint(
+ constraint
+ )
+ text += self._define_constraint_validity(constraint)
+ return text
def visit_drop_table_comment(self, drop):
return "COMMENT ON TABLE %s IS NULL" % self.preparer.format_table(
"inherits": None,
},
),
+ (
+ schema.CheckConstraint,
+ {
+ "not_valid": False,
+ },
+ ),
+ (
+ schema.ForeignKeyConstraint,
+ {
+ "not_valid": False,
+ },
+ ),
]
reflection_options = ("postgresql_ignore_search_path",)
_backslash_escapes = True
_supports_create_index_concurrently = True
_supports_drop_index_concurrently = True
+ _supports_not_valid_constraints = True
def __init__(self, json_serializer=None, json_deserializer=None, **kwargs):
default.DefaultDialect.__init__(self, **kwargs)
2,
)
self.supports_identity_columns = self.server_version_info >= (10,)
+ self._supports_not_valid_constraints = self.server_version_info >= (
+ 9,
+ 1,
+ )
def get_isolation_level_values(self, dbapi_conn):
# note the generic dialect doesn't have AUTOCOMMIT, however
from sqlalchemy import BigInteger
from sqlalchemy import bindparam
from sqlalchemy import cast
+from sqlalchemy import CheckConstraint
from sqlalchemy import Column
from sqlalchemy import Computed
from sqlalchemy import Date
from sqlalchemy import Enum
from sqlalchemy import exc
from sqlalchemy import Float
+from sqlalchemy import ForeignKeyConstraint
from sqlalchemy import func
from sqlalchemy import Identity
from sqlalchemy import Index
schema.DropIndex(idx1), "DROP INDEX test_idx1", dialect=dialect_9_1
)
+ def test_create_check_constraint_not_valid(self):
+ m = MetaData()
+
+ tbl = Table(
+ "testtbl",
+ m,
+ Column("data", Integer),
+ CheckConstraint("data = 0", postgresql_not_valid=True),
+ )
+
+ self.assert_compile(
+ schema.CreateTable(tbl),
+ "CREATE TABLE testtbl (data INTEGER, CHECK (data = 0) NOT VALID)",
+ )
+
+ dialect_9_0 = postgresql.dialect()
+ dialect_9_0._supports_not_valid_constraints = False
+ self.assert_compile(
+ schema.CreateTable(tbl),
+ "CREATE TABLE testtbl (data INTEGER, CHECK (data = 0))",
+ dialect=dialect_9_0,
+ )
+
+ def test_create_foreign_key_constraint_not_valid(self):
+ m = MetaData()
+
+ tbl = Table(
+ "testtbl",
+ m,
+ Column("a", Integer),
+ Column("b", Integer),
+ ForeignKeyConstraint(
+ "b", ["testtbl.a"], postgresql_not_valid=True
+ ),
+ )
+
+ self.assert_compile(
+ schema.CreateTable(tbl),
+ "CREATE TABLE testtbl ("
+ "a INTEGER, "
+ "b INTEGER, "
+ "FOREIGN KEY(b) REFERENCES testtbl (a) NOT VALID"
+ ")",
+ )
+
+ dialect_9_0 = postgresql.dialect()
+ dialect_9_0._supports_not_valid_constraints = False
+ self.assert_compile(
+ schema.CreateTable(tbl),
+ "CREATE TABLE testtbl ("
+ "a INTEGER, "
+ "b INTEGER, "
+ "FOREIGN KEY(b) REFERENCES testtbl (a)"
+ ")",
+ dialect=dialect_9_0,
+ )
+
def test_exclude_constraint_min(self):
m = MetaData()
tbl = Table("testtbl", m, Column("room", Integer, primary_key=True))