summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-04-10 11:54:53 +0000
committerGerrit Code Review <review@openstack.org>2015-04-10 11:54:53 +0000
commit9c852c63cd153aaa820d9bf5ebda7b5b7e1265c3 (patch)
treee1f40506d9991fff2b6fba9093bd21e44b8ca3f9
parent88dd9b0856a6ce7017a41ab1dc9e0cd00f78bfe2 (diff)
parent124239cca7f52d037163de06f1a8b38dbaffc002 (diff)
downloadoslo-db-9c852c63cd153aaa820d9bf5ebda7b5b7e1265c3.tar.gz
Merge "Handle CHECK constraint integrity in PostgreSQL"
-rw-r--r--oslo_db/exception.py17
-rw-r--r--oslo_db/sqlalchemy/exc_filters.py20
-rw-r--r--oslo_db/tests/sqlalchemy/test_exc_filters.py13
3 files changed, 50 insertions, 0 deletions
diff --git a/oslo_db/exception.py b/oslo_db/exception.py
index 111c4b5..506006c 100644
--- a/oslo_db/exception.py
+++ b/oslo_db/exception.py
@@ -87,6 +87,23 @@ class DBDuplicateEntry(DBError):
super(DBDuplicateEntry, self).__init__(inner_exception)
+class DBConstraintError(DBError):
+ """Check constraint fails for column error.
+
+ Raised when made an attempt to write to a column a value that does not
+ satisfy a CHECK constraint.
+
+ :kwarg table: the table name for which the check fails
+ :type table: str
+ :kwarg check_name: the table of the check that failed to be satisfied
+ :type check_name: str
+ """
+ def __init__(self, table, check_name, inner_exception=None):
+ self.table = table
+ self.check_name = check_name
+ super(DBConstraintError, self).__init__(inner_exception)
+
+
class DBReferenceError(DBError):
"""Foreign key violation error.
diff --git a/oslo_db/sqlalchemy/exc_filters.py b/oslo_db/sqlalchemy/exc_filters.py
index 75bd0fa..605b8a5 100644
--- a/oslo_db/sqlalchemy/exc_filters.py
+++ b/oslo_db/sqlalchemy/exc_filters.py
@@ -224,6 +224,26 @@ def _foreign_key_error(integrity_error, match, engine_name, is_disconnect):
integrity_error)
+@filters("postgresql", sqla_exc.IntegrityError,
+ r".*new row for relation \"(?P<table>.+)\" "
+ "violates check constraint "
+ "\"(?P<check_name>.+)\"")
+def _check_constraint_error(
+ integrity_error, match, engine_name, is_disconnect):
+ """Filter for check constraint errors."""
+
+ try:
+ table = match.group("table")
+ except IndexError:
+ table = None
+ try:
+ check_name = match.group("check_name")
+ except IndexError:
+ check_name = None
+
+ raise exception.DBConstraintError(table, check_name, integrity_error)
+
+
@filters("ibm_db_sa", sqla_exc.IntegrityError, r"^.*SQL0803N.*$")
def _db2_dupe_key_error(integrity_error, match, engine_name, is_disconnect):
"""Filter for DB2 duplicate key errors.
diff --git a/oslo_db/tests/sqlalchemy/test_exc_filters.py b/oslo_db/tests/sqlalchemy/test_exc_filters.py
index 5053754..3f4f277 100644
--- a/oslo_db/tests/sqlalchemy/test_exc_filters.py
+++ b/oslo_db/tests/sqlalchemy/test_exc_filters.py
@@ -354,6 +354,19 @@ class TestReferenceErrorMySQL(TestReferenceErrorSQLite,
self.assertEqual("resource_foo", matched.key_table)
+class TestConstraint(TestsExceptionFilter):
+ def test_postgresql(self):
+ matched = self._run_test(
+ "postgresql", "insert into resource some_values",
+ self.IntegrityError(
+ "new row for relation \"resource\" violates "
+ "check constraint \"ck_started_before_ended\""),
+ exception.DBConstraintError,
+ )
+ self.assertEqual("resource", matched.table)
+ self.assertEqual("ck_started_before_ended", matched.check_name)
+
+
class TestDuplicate(TestsExceptionFilter):
def _run_dupe_constraint_test(self, dialect_name, message,