From b1de3f71a8bb06f2baf8cdd8bcfcfc04687c3e83 Mon Sep 17 00:00:00 2001 From: bhagyashris Date: Fri, 18 Mar 2016 13:54:43 +0000 Subject: [PATCH] Add new filter for DBDataError exception For sqlite database if insert or update command fails due to unicode value then it raises DBError whereas for mysql using filter it raises DBDataError. To maintain consistency, added new filter which will raise DBDataError for sqlite database as well. Related-Bug: #1393871 Related-Bug: #1531400 Change-Id: Ibb61a69b1b0c6ce6172f290848f44f89e2b41d3b --- oslo_db/sqlalchemy/exc_filters.py | 2 ++ oslo_db/tests/sqlalchemy/test_exc_filters.py | 36 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/oslo_db/sqlalchemy/exc_filters.py b/oslo_db/sqlalchemy/exc_filters.py index 4ad6cf2..a728820 100644 --- a/oslo_db/sqlalchemy/exc_filters.py +++ b/oslo_db/sqlalchemy/exc_filters.py @@ -282,6 +282,8 @@ def _raise_mysql_table_doesnt_exist_asis( r".*1264.*Out of range value for column.*") @filters("mysql", sqla_exc.InternalError, r"^.*1366.*Incorrect string value:*") +@filters("sqlite", sqla_exc.ProgrammingError, + r"(?i).*You must not use 8-bit bytestrings*") def _raise_data_error(error, match, engine_name, is_disconnect): """Raise DBDataError exception for different data errors.""" diff --git a/oslo_db/tests/sqlalchemy/test_exc_filters.py b/oslo_db/tests/sqlalchemy/test_exc_filters.py index 7e6caf4..4593c04 100644 --- a/oslo_db/tests/sqlalchemy/test_exc_filters.py +++ b/oslo_db/tests/sqlalchemy/test_exc_filters.py @@ -452,6 +452,42 @@ class TestReferenceErrorMySQL(TestReferenceErrorSQLite, self.assertEqual("resource_foo", matched.key_table) +class TestDBDataErrorSQLite(_SQLAExceptionMatcher, test_base.DbTestCase): + + def setUp(self): + super(TestDBDataErrorSQLite, self).setUp() + + if six.PY3: + self.skip("SQLite database supports unicode value for python3") + + meta = sqla.MetaData(bind=self.engine) + + self.table_1 = sqla.Table( + "resource_foo", meta, + sqla.Column("name", sqla.String), + ) + self.table_1.create() + + def test_raise(self): + + matched = self.assertRaises( + exception.DBDataError, + self.engine.execute, + self.table_1.insert({'name': u'\u2713'.encode('utf-8')}) + ) + + self.assertInnerException( + matched, + "ProgrammingError", + "You must not use 8-bit bytestrings unless you use a " + "text_factory that can interpret 8-bit bytestrings " + "(like text_factory = str). It is highly recommended that " + "you instead just switch your application to Unicode strings.", + "INSERT INTO resource_foo (name) VALUES (?)", + (u'\u2713'.encode('utf-8'),) + ) + + class TestConstraint(TestsExceptionFilter): def test_postgresql(self): matched = self._run_test(