diff options
31 files changed, 491 insertions, 117 deletions
@@ -10,7 +10,6 @@ cover/ skeleton.egg-info/ build/ dist/ -doc/source/api AUTHORS .update-venv/ ChangeLog diff --git a/doc/source/api/api.rst b/doc/source/api/api.rst new file mode 100644 index 0000000..1591cc1 --- /dev/null +++ b/doc/source/api/api.rst @@ -0,0 +1,8 @@ +============= + oslo.db.api +============= + +.. automodule:: oslo.db.api + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/concurrency.rst b/doc/source/api/concurrency.rst new file mode 100644 index 0000000..527883a --- /dev/null +++ b/doc/source/api/concurrency.rst @@ -0,0 +1,8 @@ +===================== + oslo.db.concurrency +===================== + +.. automodule:: oslo.db.concurrency + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/exception.rst b/doc/source/api/exception.rst new file mode 100644 index 0000000..12b0bf0 --- /dev/null +++ b/doc/source/api/exception.rst @@ -0,0 +1,8 @@ +=================== + oslo.db.exception +=================== + +.. automodule:: oslo.db.exception + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/index.rst b/doc/source/api/index.rst new file mode 100644 index 0000000..124e451 --- /dev/null +++ b/doc/source/api/index.rst @@ -0,0 +1,12 @@ +===== + API +===== + +.. toctree:: + :maxdepth: 2 + + api + concurrency + exception + options + sqlalchemy/index diff --git a/doc/source/api/options.rst b/doc/source/api/options.rst new file mode 100644 index 0000000..40d5a83 --- /dev/null +++ b/doc/source/api/options.rst @@ -0,0 +1,8 @@ +================= + oslo.db.options +================= + +.. automodule:: oslo.db.options + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/sqlalchemy/index.rst b/doc/source/api/sqlalchemy/index.rst new file mode 100644 index 0000000..62fc2b2 --- /dev/null +++ b/doc/source/api/sqlalchemy/index.rst @@ -0,0 +1,9 @@ +==================== + oslo.db.sqlalchemy +==================== + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/doc/source/api/sqlalchemy/migration.rst b/doc/source/api/sqlalchemy/migration.rst new file mode 100644 index 0000000..2355cbc --- /dev/null +++ b/doc/source/api/sqlalchemy/migration.rst @@ -0,0 +1,8 @@ +============================== + oslo.db.sqlalchemy.migration +============================== + +.. automodule:: oslo.db.sqlalchemy.migration + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/sqlalchemy/models.rst b/doc/source/api/sqlalchemy/models.rst new file mode 100644 index 0000000..b902320 --- /dev/null +++ b/doc/source/api/sqlalchemy/models.rst @@ -0,0 +1,8 @@ +=========================== + oslo.db.sqlalchemy.models +=========================== + +.. automodule:: oslo.db.sqlalchemy.models + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/sqlalchemy/provision.rst b/doc/source/api/sqlalchemy/provision.rst new file mode 100644 index 0000000..7d003d7 --- /dev/null +++ b/doc/source/api/sqlalchemy/provision.rst @@ -0,0 +1,8 @@ +============================== + oslo.db.sqlalchemy.provision +============================== + +.. automodule:: oslo.db.sqlalchemy.provision + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/sqlalchemy/session.rst b/doc/source/api/sqlalchemy/session.rst new file mode 100644 index 0000000..14e6f5a --- /dev/null +++ b/doc/source/api/sqlalchemy/session.rst @@ -0,0 +1,8 @@ +============================ + oslo.db.sqlalchemy.session +============================ + +.. automodule:: oslo.db.sqlalchemy.session + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/sqlalchemy/test_base.rst b/doc/source/api/sqlalchemy/test_base.rst new file mode 100644 index 0000000..7794170 --- /dev/null +++ b/doc/source/api/sqlalchemy/test_base.rst @@ -0,0 +1,8 @@ +============================== + oslo.db.sqlalchemy.test_base +============================== + +.. automodule:: oslo.db.sqlalchemy.test_base + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/sqlalchemy/test_migrations.rst b/doc/source/api/sqlalchemy/test_migrations.rst new file mode 100644 index 0000000..4b3c81c --- /dev/null +++ b/doc/source/api/sqlalchemy/test_migrations.rst @@ -0,0 +1,8 @@ +==================================== + oslo.db.sqlalchemy.test_migrations +==================================== + +.. automodule:: oslo.db.sqlalchemy.test_migrations + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/sqlalchemy/utils.rst b/doc/source/api/sqlalchemy/utils.rst new file mode 100644 index 0000000..cccc93f --- /dev/null +++ b/doc/source/api/sqlalchemy/utils.rst @@ -0,0 +1,8 @@ +========================== + oslo.db.sqlalchemy.utils +========================== + +.. automodule:: oslo.db.sqlalchemy.utils + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/history.rst b/doc/source/history.rst new file mode 100644 index 0000000..69ed4fe --- /dev/null +++ b/doc/source/history.rst @@ -0,0 +1 @@ +.. include:: ../../ChangeLog diff --git a/doc/source/index.rst b/doc/source/index.rst index 037fe74..5e96766 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,19 +1,21 @@ -Welcome to oslo.db documentation! -================================= +========= + oslo.db +========= The Oslo database handling library. Provides database connectivity to the different backends and helper utils. -Contents: ---------- +Contents +-------- .. toctree:: :maxdepth: 2 - readme installation usage + api/index contributing + history Indices and tables ------------------ diff --git a/doc/source/installation.rst b/doc/source/installation.rst index 254bd9b..96e0ec2 100644 --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -6,11 +6,6 @@ At the command line:: $ pip install oslo.db -Or, if you have virtualenvwrapper installed:: - - $ mkvirtualenv - $ pip install oslo.db - You will also need to install at least one SQL backend:: $ pip install MySQL-python @@ -30,4 +25,4 @@ your distro. On Ubuntu this is done as follows:: The installation of MySQL-python will fail if libmysqlclient-dev is not installed first. Note that even in a virtual environment the MySQL package will -be installed system wide.
\ No newline at end of file +be installed system wide. diff --git a/doc/source/readme.rst b/doc/source/readme.rst deleted file mode 100644 index a6210d3..0000000 --- a/doc/source/readme.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../README.rst diff --git a/doc/source/usage.rst b/doc/source/usage.rst index 0591ebe..f352ee9 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -1,12 +1,13 @@ -======== -Usage -======== +======= + Usage +======= -To use oslo.db in a project:: +To use oslo.db in a project: -* Session Handling +Session Handling +================ - .. code:: python +.. code:: python from oslo.config import cfg from oslo.db.sqlalchemy import session as db_session @@ -28,9 +29,10 @@ To use oslo.db in a project:: return facade.get_session(**kwargs) -* Base class for models usage +Base class for models usage +=========================== - .. code:: python +.. code:: python from oslo.db import models @@ -41,9 +43,10 @@ To use oslo.db in a project:: ... -* DB API backend support +DB API backend support +====================== - .. code:: python +.. code:: python from oslo.config import cfg from oslo.db import api as db_api @@ -62,4 +65,3 @@ To use oslo.db in a project:: # DB-API method def do_something(somethind_id): return IMPL.do_something(somethind_id) - diff --git a/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-critical.po b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-critical.po new file mode 100644 index 0000000..18191a3 --- /dev/null +++ b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-critical.po @@ -0,0 +1,21 @@ +# Translations template for heat. +# Copyright (C) 2014 ORGANIZATION +# This file is distributed under the same license as the heat project. +# +# Translators: +# Andi Chandler <andi@gowling.com>, 2014 +msgid "" +msgstr "" +"Project-Id-Version: oslo.db\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2014-09-12 06:00+0000\n" +"PO-Revision-Date: 2014-09-02 09:17+0000\n" +"Last-Translator: Andi Chandler <andi@gowling.com>\n" +"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/" +"oslodb/language/en_GB/)\n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" diff --git a/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-error.po b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-error.po new file mode 100644 index 0000000..8e69aa6 --- /dev/null +++ b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-error.po @@ -0,0 +1,55 @@ +# Translations template for oslo.db. +# Copyright (C) 2014 ORGANIZATION +# This file is distributed under the same license as the oslo.db project. +# +# Translators: +# Andi Chandler <andi@gowling.com>, 2014 +msgid "" +msgstr "" +"Project-Id-Version: oslo.db\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2014-09-12 06:00+0000\n" +"PO-Revision-Date: 2014-09-02 09:17+0000\n" +"Last-Translator: Andi Chandler <andi@gowling.com>\n" +"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/" +"oslodb/language/en_GB/)\n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: oslo/db/api.py:106 +msgid "DB exceeded retry limit." +msgstr "DB exceeded retry limit." + +#: oslo/db/api.py:110 +msgid "DB connection error." +msgstr "DB connection error." + +#: oslo/db/concurrency.py:64 +msgid "'eventlet' is required for TpoolDbapiWrapper." +msgstr "'eventlet' is required for TpoolDbapiWrapper." + +#: oslo/db/sqlalchemy/exc_filters.py:277 +#, python-format +msgid "DBAPIError exception wrapped from %s" +msgstr "DBAPIError exception wrapped from %s" + +#: oslo/db/sqlalchemy/exc_filters.py:288 +msgid "DB exception wrapped." +msgstr "DB exception wrapped." + +#: oslo/db/sqlalchemy/test_migrations.py:271 +#, python-format +msgid "Failed to migrate to version %(ver)s on engine %(eng)s" +msgstr "Failed to migrate to version %(ver)s on engine %(eng)s" + +#: oslo/db/sqlalchemy/migration_cli/ext_migrate.py:61 +msgid "" +"Migration number for migrate plugin must be valid integer or empty, if you " +"want to downgrade to initial state" +msgstr "" +"Migration number for migrate plugin must be valid integer or empty, if you " +"want to downgrade to initial state" diff --git a/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-info.po b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-info.po new file mode 100644 index 0000000..fc898eb --- /dev/null +++ b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-info.po @@ -0,0 +1,31 @@ +# Translations template for oslo.db. +# Copyright (C) 2014 ORGANIZATION +# This file is distributed under the same license as the oslo.db project. +# +# Translators: +# Andi Chandler <andi@gowling.com>, 2014 +msgid "" +msgstr "" +"Project-Id-Version: oslo.db\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2014-09-12 06:00+0000\n" +"PO-Revision-Date: 2014-09-02 09:18+0000\n" +"Last-Translator: Andi Chandler <andi@gowling.com>\n" +"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/" +"oslodb/language/en_GB/)\n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: oslo/db/sqlalchemy/utils.py:433 +#, python-format +msgid "Deleting duplicated row with id: %(id)s from table: %(table)s" +msgstr "Deleting duplicated row with id: %(id)s from table: %(table)s" + +#: oslo/db/sqlalchemy/utils.py:694 +#, python-format +msgid "The %(backend)s backend is unavailable: %(exception)s" +msgstr "The %(backend)s backend is unavailable: %(exception)s" diff --git a/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-warning.po b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-warning.po new file mode 100644 index 0000000..bf00654 --- /dev/null +++ b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-warning.po @@ -0,0 +1,41 @@ +# Translations template for oslo.db. +# Copyright (C) 2014 ORGANIZATION +# This file is distributed under the same license as the oslo.db project. +# +# Translators: +# Andi Chandler <andi@gowling.com>, 2014 +msgid "" +msgstr "" +"Project-Id-Version: oslo.db\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2014-09-12 06:00+0000\n" +"PO-Revision-Date: 2014-09-02 09:17+0000\n" +"Last-Translator: Andi Chandler <andi@gowling.com>\n" +"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/" +"oslodb/language/en_GB/)\n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: oslo/db/sqlalchemy/session.py:458 +msgid "Unable to detect effective SQL mode" +msgstr "Unable to detect effective SQL mode" + +#: oslo/db/sqlalchemy/session.py:465 +#, python-format +msgid "" +"MySQL SQL mode is '%s', consider enabling TRADITIONAL or STRICT_ALL_TABLES" +msgstr "" +"MySQL SQL mode is '%s', consider enabling TRADITIONAL or STRICT_ALL_TABLES" + +#: oslo/db/sqlalchemy/session.py:521 +#, python-format +msgid "SQL connection failed. %s attempts left." +msgstr "SQL connection failed. %s attempts left." + +#: oslo/db/sqlalchemy/utils.py:100 +msgid "Id not in sort_keys; is sort_keys unique?" +msgstr "Id not in sort_keys; is sort_keys unique?" diff --git a/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db.po b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db.po new file mode 100644 index 0000000..c1157c7 --- /dev/null +++ b/oslo.db/locale/en_GB/LC_MESSAGES/oslo.db.po @@ -0,0 +1,94 @@ +# English (United Kingdom) translations for oslo.db. +# Copyright (C) 2014 ORGANIZATION +# This file is distributed under the same license as the oslo.db project. +# +# Translators: +# Andi Chandler <andi@gowling.com>, 2014 +msgid "" +msgstr "" +"Project-Id-Version: oslo.db\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2014-09-12 06:00+0000\n" +"PO-Revision-Date: 2014-09-02 09:18+0000\n" +"Last-Translator: Andi Chandler <andi@gowling.com>\n" +"Language-Team: English (United Kingdom) " +"(http://www.transifex.com/projects/p/oslodb/language/en_GB/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: oslo/db/exception.py:133 +msgid "Invalid Parameter: Encoding directive wasn't provided." +msgstr "Invalid Parameter: Encoding directive wasn't provided." + +#: oslo/db/exception.py:161 +msgid "Sort key supplied was not valid." +msgstr "Sort key supplied was not valid." + +#: oslo/db/sqlalchemy/migration.py:72 +msgid "version should be an integer" +msgstr "version should be an integer" + +#: oslo/db/sqlalchemy/migration.py:108 +#, python-format +msgid "" +"Tables \"%s\" have non utf8 collation, please make sure all tables are " +"CHARSET=utf8" +msgstr "" +"Tables \"%s\" have non utf8 collation, please make sure all tables are " +"CHARSET=utf8" + +#: oslo/db/sqlalchemy/migration.py:132 +msgid "" +"The database is not under version control, but has tables. Please stamp " +"the current version of the schema manually." +msgstr "" +"The database is not under version control, but has tables. Please stamp " +"the current version of the schema manually." + +#: oslo/db/sqlalchemy/utils.py:122 +msgid "Unknown sort direction, must be 'desc' or 'asc'" +msgstr "Unknown sort direction, must be 'desc' or 'asc'" + +#: oslo/db/sqlalchemy/utils.py:165 +#, python-format +msgid "" +"There is no `deleted` column in `%s` table. Project doesn't use soft-" +"deleted feature." +msgstr "" +"There is no `deleted` column in `%s` table. Project doesn't use soft-" +"deleted feature." + +#: oslo/db/sqlalchemy/utils.py:179 +#, python-format +msgid "There is no `project_id` column in `%s` table." +msgstr "There is no `project_id` column in `%s` table." + +#: oslo/db/sqlalchemy/utils.py:291 +msgid "model should be a subclass of ModelBase" +msgstr "model should be a subclass of ModelBase" + +#: oslo/db/sqlalchemy/utils.py:340 +#, python-format +msgid "" +"Please specify column %s in col_name_col_instance param. It is required " +"because column has unsupported type by SQLite." +msgstr "" +"Please specify column %s in col_name_col_instance param. It is required " +"because column has unsupported type by SQLite." + +#: oslo/db/sqlalchemy/utils.py:346 +#, python-format +msgid "" +"col_name_col_instance param has wrong type of column instance for column " +"%s It should be instance of sqlalchemy.Column." +msgstr "" +"col_name_col_instance param has wrong type of column instance for column " +"%s It should be instance of sqlalchemy.Column." + +#: oslo/db/sqlalchemy/utils.py:454 +msgid "Unsupported id columns type" +msgstr "Unsupported id columns type" + diff --git a/oslo/db/sqlalchemy/exc_filters.py b/oslo/db/sqlalchemy/exc_filters.py index c03c4b4..b3da401 100644 --- a/oslo/db/sqlalchemy/exc_filters.py +++ b/oslo/db/sqlalchemy/exc_filters.py @@ -169,7 +169,7 @@ def _sqlite_dupe_key_error(integrity_error, match, engine_name, is_disconnect): @filters("sqlite", sqla_exc.IntegrityError, - r".*SQL error: foreign key constraint failed") + r"(?i).*foreign key constraint failed") @filters("postgresql", sqla_exc.IntegrityError, r".*on table \"(?P<table>[^\"]+)\" violates " "foreign key constraint \"(?P<constraint>[^\"]+)\"\s*\n" @@ -177,13 +177,13 @@ def _sqlite_dupe_key_error(integrity_error, match, engine_name, is_disconnect): "is not present in table " "\"(?P<key_table>[^\"]+)\".") @filters("mysql", sqla_exc.IntegrityError, - r".* Cannot add or update a child row: " - "a foreign key constraint fails " - "\((?P<table>.+), CONSTRAINT (?P<constraint>.+) " - "FOREIGN KEY \((?P<key>.+)\) " - "REFERENCES (?P<key_table>.+) \(.+\)\)") + r".* 'Cannot add or update a child row: " + 'a foreign key constraint fails \([`"].+[`"]\.[`"](?P<table>.+)[`"], ' + 'CONSTRAINT [`"](?P<constraint>.+)[`"] FOREIGN KEY ' + '\([`"](?P<key>.+)[`"]\) REFERENCES [`"](?P<key_table>.+)[`"] ') def _foreign_key_error(integrity_error, match, engine_name, is_disconnect): """Filter for foreign key errors.""" + try: table = match.group("table") except IndexError: diff --git a/oslo/db/sqlalchemy/migration.py b/oslo/db/sqlalchemy/migration.py index d7a17b3..f1cecdd 100644 --- a/oslo/db/sqlalchemy/migration.py +++ b/oslo/db/sqlalchemy/migration.py @@ -93,7 +93,7 @@ def _db_schema_sanity_check(engine): onlyutf8_sql = ('SELECT TABLE_NAME,TABLE_COLLATION ' 'from information_schema.TABLES ' 'where TABLE_SCHEMA=%s and ' - 'TABLE_COLLATION NOT LIKE "%%utf8%%"') + 'TABLE_COLLATION NOT LIKE \'%%utf8%%\'') # NOTE(morganfainberg): exclude the sqlalchemy-migrate and alembic # versioning tables from the tables we need to verify utf8 status on. diff --git a/oslo/db/sqlalchemy/test_migrations.py b/oslo/db/sqlalchemy/test_migrations.py index 8bfdcfb..176e0dd 100644 --- a/oslo/db/sqlalchemy/test_migrations.py +++ b/oslo/db/sqlalchemy/test_migrations.py @@ -45,10 +45,9 @@ class WalkVersionsMixin(object): abstract class mixin. `INIT_VERSION`, `REPOSITORY` and `migration_api` attributes must be implemented in subclasses. - .. _auxiliary-dynamic-methods: + .. _auxiliary-dynamic-methods: Auxiliary Methods - Auxiliary methods - ----------------- + Auxiliary Methods: `migrate_up` and `migrate_down` instance methods of the class can be used with auxiliary methods named `_pre_upgrade_<revision_id>`, @@ -59,16 +58,16 @@ class WalkVersionsMixin(object): `_pre_upgrade_<revision_id>`, `_check_<revision_id>`, `_post_downgrade_<revision_id>` implementation: - * `_pre_upgrade_<revision_id>`: provide a data appropriate to a - next revision. Should be used an id of revision which going to be - applied. + * `_pre_upgrade_<revision_id>`: provide a data appropriate to + a next revision. Should be used an id of revision which + going to be applied. - * `_check_<revision_id>`: Insert, select, delete operations with - newly applied changes. The data provided by - `_pre_upgrade_<revision_id>` will be used. + * `_check_<revision_id>`: Insert, select, delete operations + with newly applied changes. The data provided by + `_pre_upgrade_<revision_id>` will be used. - *`_post_downgrade_<revision_id>`: check for absence (inability to - use) changes provided by reverted revision. + * `_post_downgrade_<revision_id>`: check for absence + (inability to use) changes provided by reverted revision. Execution order of auxiliary methods when revision is upgrading: @@ -79,6 +78,7 @@ class WalkVersionsMixin(object): `downgrade` => `_post_downgrade_###` .. _migrate: https://sqlalchemy-migrate.readthedocs.org/en/latest/ + """ @abc.abstractproperty @@ -213,7 +213,7 @@ class WalkVersionsMixin(object): :type version: str :keyword with_data: Whether to verify the absence of changes from migration(s) being downgraded, see - :ref:`auxiliary-dynamic-methods`. + :ref:`auxiliary-dynamic-methods <Auxiliary Methods>`. :type with_data: Bool """ @@ -245,7 +245,7 @@ class WalkVersionsMixin(object): :param version: id of revision to upgrade. :type version: str :keyword with_data: Whether to verify the applied changes with data, - see :ref:`auxiliary-dynamic-methods`. + see :ref:`auxiliary-dynamic-methods <Auxiliary Methods>`. :type with_data: Bool """ # NOTE(sdague): try block is here because it's impossible to debug diff --git a/requirements.txt b/requirements.txt index a2c2f6e..205a787 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,9 +5,9 @@ alembic>=0.6.4 Babel>=1.3 iso8601>=0.1.9 -oslo.i18n>=0.2.0 # Apache-2.0 +oslo.i18n>=0.3.0 # Apache-2.0 oslo.config>=1.4.0.0a3 -oslo.utils>=0.2.0 # Apache-2.0 +oslo.utils>=0.3.0 # Apache-2.0 SQLAlchemy>=0.8.4,<=0.8.99,>=0.9.7,<=0.9.99 -sqlalchemy-migrate>=0.9.1 +sqlalchemy-migrate>=0.9.1,!=0.9.2 stevedore>=0.14 @@ -59,4 +59,4 @@ output_file = oslo.db/locale/oslo.db.pot # NOTE(viktors): uncomment ``warnerrors`` line, when setup.cfg we then # want to treat sphinx warnings as errors # warnerrors = True -autodoc_index_modules = True +#autodoc_index_modules = True diff --git a/test-requirements.txt b/test-requirements.txt index 1a190ca..62ced1b 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -6,14 +6,14 @@ hacking>=0.9.2,<0.10 coverage>=3.6 discover -doc8 +doc8 # Apache-2.0 fixtures>=0.3.14 MySQL-python psycopg2 python-subunit>=0.0.18 sphinx>=1.1.2,!=1.2.0,<1.3 oslosphinx>=2.2.0.0a2 -oslotest>=1.1.0.0a1 +oslotest>=1.1.0.0a2 testrepository>=0.0.18 testscenarios>=0.4 testtools>=0.9.34 diff --git a/tests/sqlalchemy/test_exc_filters.py b/tests/sqlalchemy/test_exc_filters.py index b6b1375..d0ea38b 100644 --- a/tests/sqlalchemy/test_exc_filters.py +++ b/tests/sqlalchemy/test_exc_filters.py @@ -195,87 +195,112 @@ class TestFallthroughsAndNonDBAPI(TestsExceptionFilter): self.assertEqual("mysqldb has an attribute error", matched.args[0]) -class TestRaiseReferenceError(TestsExceptionFilter): - def test_postgresql(self): - e = self._run_test( - "postgresql", - "INSERT SOMETHING", - self.IntegrityError( - "insert or update on table " - "\"resource_entity\" " - "violates foreign key constraint " - "\"resource_entity_entity_id_fkey\"\n" - "DETAIL: Key " - "(entity_id)=(74b5da71-5a9c-4f89-a8e9-4a2d856e6c29) " - "is not present in table \"entity\".\n" - "'INSERT INTO resource_entity (resource_id, entity_id, name) " - "VALUES (%(resource_id)s, " - "%(entity_id)s, %(name)s)' " - "{'entity_id': '74b5da71-5a9c-4f89-a8e9-4a2d856e6c29', " - "'name': u'foo', " - "'resource_id': 'ffb12cb4-d955-4d96-a315-5f48ea161eef'}"), +class TestReferenceErrorSQLite(test_base.DbTestCase): + + def setUp(self): + super(TestReferenceErrorSQLite, self).setUp() + + meta = sqla.MetaData(bind=self.engine) + + table_1 = sqla.Table( + "resource_foo", meta, + sqla.Column("id", sqla.Integer, primary_key=True), + sqla.Column("foo", sqla.Integer), + mysql_engine='InnoDB', + mysql_charset='utf8', + ) + table_1.create() + + self.table_2 = sqla.Table( + "resource_entity", meta, + sqla.Column("id", sqla.Integer, primary_key=True), + sqla.Column("foo_id", sqla.Integer, + sqla.ForeignKey("resource_foo.id", name="foo_fkey")), + mysql_engine='InnoDB', + mysql_charset='utf8', + ) + self.table_2.create() + + def test_raise(self): + self.engine.execute("PRAGMA foreign_keys = ON;") + + e = self.assertRaises( exception.DBReferenceError, + self.engine.execute, + self.table_2.insert({'id': 1, 'foo_id': 2}) ) - self.assertEqual("resource_entity", e.table) - self.assertEqual("resource_entity_entity_id_fkey", e.constraint) - self.assertEqual("entity_id", e.key) - self.assertEqual("entity", e.key_table) + self.assertEqual( - "(IntegrityError) insert or update on table " - "\"resource_entity\" violates foreign key constraint " - "\"resource_entity_entity_id_fkey\"\n" - "DETAIL: Key (entity_id)=(74b5da71-5a9c-4f89-a8e9-4a2d856e6c29) " - "is not present in table \"entity\".\n" - "'INSERT INTO resource_entity (resource_id, entity_id, name) " - "VALUES (%(resource_id)s, %(entity_id)s, %(name)s)' " - "{'entity_id': '74b5da71-5a9c-4f89-a8e9-4a2d856e6c29', " - "'name': u'foo', " - "'resource_id': 'ffb12cb4-d955-4d96-a315-5f48ea161eef'} " - "'INSERT SOMETHING' ()", - str(e)) + "(IntegrityError) FOREIGN KEY constraint failed u'INSERT INTO " + "resource_entity (id, foo_id) VALUES (?, ?)' (1, 2)".lower(), + str(e).lower()) + self.assertIsNone(e.table) + self.assertIsNone(e.constraint) + self.assertIsNone(e.key) + self.assertIsNone(e.key_table) - def test_mysql(self): - e = self._run_test( - "mysql", - "INSERT SOMETHING", - self.IntegrityError( - "Cannot add or update a child row: " - "a foreign key constraint fails " - "(resource_entity, CONSTRAINT resource_entity_entity_id_fkey " - "FOREIGN KEY (entity_id) " - "REFERENCES entity (entity_id))" - ), + +class TestReferenceErrorPostgreSQL(TestReferenceErrorSQLite, + test_base.PostgreSQLOpportunisticTestCase): + def test_raise(self): + e = self.assertRaises( exception.DBReferenceError, + self.engine.execute, + self.table_2.insert({'id': 1, 'foo_id': 2}) ) + + self.assertIn( + "(IntegrityError) insert or update on table \"resource_entity\" " + "violates foreign key constraint \"foo_fkey\"\nDETAIL: Key " + "(foo_id)=(2) is not present in table \"resource_foo\".\n" + " 'INSERT INTO resource_entity (id, foo_id) VALUES (%(id)s, " + "%(foo_id)s)'", str(e)) self.assertEqual("resource_entity", e.table) - self.assertEqual("resource_entity_entity_id_fkey", e.constraint) - self.assertEqual("entity_id", e.key) - self.assertEqual("entity", e.key_table) + self.assertEqual("foo_fkey", e.constraint) + self.assertEqual("foo_id", e.key) + self.assertEqual("resource_foo", e.key_table) + + +class TestReferenceErrorMySQL(TestReferenceErrorSQLite, + test_base.MySQLOpportunisticTestCase): + def test_raise(self): + e = self.assertRaises( + exception.DBReferenceError, + self.engine.execute, + self.table_2.insert({'id': 1, 'foo_id': 2}) + ) + self.assertEqual( - "(IntegrityError) Cannot add or update a child row: " - "a foreign key constraint fails " - "(resource_entity, CONSTRAINT resource_entity_entity_id_fkey " - "FOREIGN KEY (entity_id) REFERENCES entity (entity_id)) " - "'INSERT SOMETHING' ()", + "(IntegrityError) (1452, 'Cannot add or update a child row: a " + "foreign key constraint fails (`{0}`.`resource_entity`, " + "CONSTRAINT `foo_fkey` FOREIGN KEY (`foo_id`) REFERENCES " + "`resource_foo` (`id`))') 'INSERT INTO resource_entity (id, foo_id" + ") VALUES (%s, %s)' (1, 2)".format(self.engine.url.database), str(e)) + self.assertEqual("resource_entity", e.table) + self.assertEqual("foo_fkey", e.constraint) + self.assertEqual("foo_id", e.key) + self.assertEqual("resource_foo", e.key_table) - def test_sqlite(self): - e = self._run_test( - "sqlite", - "INSERT SOMETHING", - self.IntegrityError( - "SQL error: foreign key constraint failed" - ), + def test_raise_ansi_quotes(self): + self.engine.execute("SET SESSION sql_mode = 'ANSI';") + e = self.assertRaises( exception.DBReferenceError, + self.engine.execute, + self.table_2.insert({'id': 1, 'foo_id': 2}) ) - self.assertIsNone(e.table) - self.assertIsNone(e.constraint) - self.assertIsNone(e.key) - self.assertIsNone(e.key_table) + self.assertEqual( - "(IntegrityError) SQL error: foreign key " - "constraint failed 'INSERT SOMETHING' ()", + "(IntegrityError) (1452, 'Cannot add or update a child row: a " + 'foreign key constraint fails ("{0}"."resource_entity", ' + 'CONSTRAINT "foo_fkey" FOREIGN KEY ("foo_id") REFERENCES ' + '"resource_foo" ("id"))\') \'INSERT INTO resource_entity (id, ' + "foo_id) VALUES (%s, %s)' (1, 2)".format(self.engine.url.database), str(e)) + self.assertEqual("resource_entity", e.table) + self.assertEqual("foo_fkey", e.constraint) + self.assertEqual("foo_id", e.key) + self.assertEqual("resource_foo", e.key_table) class TestDuplicate(TestsExceptionFilter): |