summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--doc/source/api/api.rst8
-rw-r--r--doc/source/api/concurrency.rst8
-rw-r--r--doc/source/api/exception.rst8
-rw-r--r--doc/source/api/index.rst12
-rw-r--r--doc/source/api/options.rst8
-rw-r--r--doc/source/api/sqlalchemy/index.rst9
-rw-r--r--doc/source/api/sqlalchemy/migration.rst8
-rw-r--r--doc/source/api/sqlalchemy/models.rst8
-rw-r--r--doc/source/api/sqlalchemy/provision.rst8
-rw-r--r--doc/source/api/sqlalchemy/session.rst8
-rw-r--r--doc/source/api/sqlalchemy/test_base.rst8
-rw-r--r--doc/source/api/sqlalchemy/test_migrations.rst8
-rw-r--r--doc/source/api/sqlalchemy/utils.rst8
-rw-r--r--doc/source/history.rst1
-rw-r--r--doc/source/index.rst12
-rw-r--r--doc/source/installation.rst7
-rw-r--r--doc/source/readme.rst1
-rw-r--r--doc/source/usage.rst24
-rw-r--r--oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-critical.po21
-rw-r--r--oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-error.po55
-rw-r--r--oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-info.po31
-rw-r--r--oslo.db/locale/en_GB/LC_MESSAGES/oslo.db-log-warning.po41
-rw-r--r--oslo.db/locale/en_GB/LC_MESSAGES/oslo.db.po94
-rw-r--r--oslo/db/sqlalchemy/exc_filters.py12
-rw-r--r--oslo/db/sqlalchemy/migration.py2
-rw-r--r--oslo/db/sqlalchemy/test_migrations.py26
-rw-r--r--requirements.txt6
-rw-r--r--setup.cfg2
-rw-r--r--test-requirements.txt4
-rw-r--r--tests/sqlalchemy/test_exc_filters.py159
31 files changed, 491 insertions, 117 deletions
diff --git a/.gitignore b/.gitignore
index cbbf8f8..a447b46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/setup.cfg b/setup.cfg
index 78097e8..119e2a8 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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):