summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/installation.rst27
-rw-r--r--oslo/db/sqlalchemy/test_base.py2
-rw-r--r--oslo/db/sqlalchemy/utils.py13
-rw-r--r--test-requirements.txt3
-rw-r--r--tests/sqlalchemy/test_utils.py32
-rw-r--r--tox.ini2
6 files changed, 68 insertions, 11 deletions
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
index 5c01c7a..254bd9b 100644
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -4,9 +4,30 @@ Installation
At the command line::
- $ pip install
+ $ pip install oslo.db
Or, if you have virtualenvwrapper installed::
- $ mkvirtualenv
- $ pip install \ No newline at end of file
+ $ mkvirtualenv
+ $ pip install oslo.db
+
+You will also need to install at least one SQL backend::
+
+ $ pip install MySQL-python
+
+Or::
+
+ $ pip install pysqlite
+
+Using with MySQL
+----------------
+
+If using MySQL make sure to install the MySQL client development package for
+your distro. On Ubuntu this is done as follows::
+
+ $ sudo apt-get install libmysqlclient-dev
+ $ pip install MySQL-python
+
+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
diff --git a/oslo/db/sqlalchemy/test_base.py b/oslo/db/sqlalchemy/test_base.py
index 7664faa..544568e 100644
--- a/oslo/db/sqlalchemy/test_base.py
+++ b/oslo/db/sqlalchemy/test_base.py
@@ -151,10 +151,12 @@ class OpportunisticTestCase(DbTestCase):
class MySQLOpportunisticFixture(OpportunisticFixture):
DRIVER = 'mysql'
+ DBNAME = '' # connect to MySQL server, but not to the openstack_citest db
class PostgreSQLOpportunisticFixture(OpportunisticFixture):
DRIVER = 'postgresql'
+ DBNAME = 'postgres' # PostgreSQL requires the db name here,use service one
class MySQLOpportunisticTestCase(OpportunisticTestCase):
diff --git a/oslo/db/sqlalchemy/utils.py b/oslo/db/sqlalchemy/utils.py
index 04eb7ce..83821f7 100644
--- a/oslo/db/sqlalchemy/utils.py
+++ b/oslo/db/sqlalchemy/utils.py
@@ -418,7 +418,7 @@ def drop_old_duplicate_entries_from_table(migrate_engine, table_name,
columns_for_select, group_by=columns_for_group_by,
having=func.count(table.c.id) > 1)
- for row in migrate_engine.execute(duplicated_rows_select):
+ for row in migrate_engine.execute(duplicated_rows_select).fetchall():
# NOTE(boris-42): Do not remove row that has the biggest ID.
delete_condition = table.c.id != row[0]
is_none = None # workaround for pyflakes
@@ -612,8 +612,15 @@ def _change_deleted_column_type_to_id_type_sqlite(migrate_engine, table_name,
if not isinstance(constraint, CheckConstraint):
return False
sqltext = str(constraint.sqltext)
- return (sqltext.endswith("deleted in (0, 1)") or
- sqltext.endswith("deleted IN (:deleted_1, :deleted_2)"))
+ # NOTE(I159): in order to omit the CHECK constraint corresponding
+ # to `deleted` column we have to test these patterns which may
+ # vary depending on the SQLAlchemy version used.
+ constraint_markers = (
+ "deleted in (0, 1)",
+ "deleted IN (:deleted_1, :deleted_2)",
+ "deleted IN (:param_1, :param_2)"
+ )
+ return any(sqltext.endswith(marker) for marker in constraint_markers)
constraints = []
for constraint in table.constraints:
diff --git a/test-requirements.txt b/test-requirements.txt
index c940f8c..f0a218c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,9 +1,10 @@
-hacking>=0.8.0,<0.9
+hacking>=0.9.1,<0.10
coverage>=3.6
discover
fixtures>=0.3.14
MySQL-python
+psycopg2
python-subunit>=0.0.18
sphinx>=1.2.1,<1.3
oslosphinx
diff --git a/tests/sqlalchemy/test_utils.py b/tests/sqlalchemy/test_utils.py
index 36a2b14..a24a83a 100644
--- a/tests/sqlalchemy/test_utils.py
+++ b/tests/sqlalchemy/test_utils.py
@@ -183,9 +183,6 @@ class TestPaginateQuery(test_base.BaseTestCase):
class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
"""Class for testing utils that are used in db migrations."""
- def setUp(self):
- super(TestMigrationUtils, self).setUp()
-
def _populate_db_for_drop_duplicate_entries(self, engine, meta,
table_name):
values = [
@@ -241,6 +238,18 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
for id_ in expected_ids:
self.assertTrue(id_ in real_ids)
+ def test_drop_dup_entries_in_file_conn(self):
+ table_name = "__test_tmp_table__"
+ tmp_db_file = self.create_tempfiles([['name', '']], ext='.sql')[0]
+ in_file_engine = session.EngineFacade(
+ 'sqlite:///%s' % tmp_db_file).get_engine()
+ meta = MetaData()
+ meta.bind = in_file_engine
+ test_table, values = self._populate_db_for_drop_duplicate_entries(
+ in_file_engine, meta, table_name)
+ utils.drop_old_duplicate_entries_from_table(
+ in_file_engine, table_name, False, 'b', 'c')
+
def test_drop_old_duplicate_entries_from_table_soft_delete(self):
table_name = "__test_tmp_table__"
@@ -441,6 +450,23 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
self.assertTrue(isinstance(table.c.foo.type, NullType))
self.assertTrue(isinstance(table.c.deleted.type, Boolean))
+ def test_change_deleted_column_type_drops_check_constraint(self):
+ table_name = 'abc'
+ meta = MetaData()
+ engine = self.engines['sqlite']
+ meta.bind = engine
+ table = Table(table_name, meta,
+ Column('id', Integer, primary_key=True),
+ Column('deleted', Boolean))
+ table.create()
+
+ utils._change_deleted_column_type_to_id_type_sqlite(engine,
+ table_name)
+ table = Table(table_name, meta, autoload=True)
+ # NOTE(I159): if the CHECK constraint has been dropped (expected
+ # behavior), any integer value can be inserted, otherwise only 1 or 0.
+ engine.execute(table.insert({'deleted': 10}))
+
def test_utils_drop_unique_constraint(self):
table_name = "__test_tmp_table__"
uc_name = 'uniq_foo'
diff --git a/tox.ini b/tox.ini
index fef9a35..b4c00d4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -35,7 +35,7 @@ commands =
# E123, E125 skipped as they are invalid PEP-8.
show-source = True
-ignore = E123,E125,H803
+ignore = E123,E125,E128,E265,H305,H307,H402,H405,H703,H803,H904
builtins = _
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build