diff options
author | Jenkins <jenkins@review.openstack.org> | 2015-04-10 11:54:53 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2015-04-10 11:54:53 +0000 |
commit | 9c852c63cd153aaa820d9bf5ebda7b5b7e1265c3 (patch) | |
tree | e1f40506d9991fff2b6fba9093bd21e44b8ca3f9 | |
parent | 88dd9b0856a6ce7017a41ab1dc9e0cd00f78bfe2 (diff) | |
parent | 124239cca7f52d037163de06f1a8b38dbaffc002 (diff) | |
download | oslo-db-9c852c63cd153aaa820d9bf5ebda7b5b7e1265c3.tar.gz |
Merge "Handle CHECK constraint integrity in PostgreSQL"
-rw-r--r-- | oslo_db/exception.py | 17 | ||||
-rw-r--r-- | oslo_db/sqlalchemy/exc_filters.py | 20 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_exc_filters.py | 13 |
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, |