diff --git a/docs/changelog.rst b/docs/changelog.rst index 89a8238..f09e5c9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,7 @@ 0.5.5 ----- +- url parameter can also be an Engine instance (this usage is discouraged though sometimes necessary) - added support for SQLAlchemy 0.6 (missing oracle and firebird) by Michael Bayer - alter, create, drop column / rename table / rename index constructs now accept `alter_metadata` parameter. If True, it will modify Column/Table objects according to changes. Otherwise, everything will be untouched. - complete refactoring of :class:`~migrate.changeset.schema.ColumnDelta` (fixes issue 23) diff --git a/migrate/versioning/util/__init__.py b/migrate/versioning/util/__init__.py index 6e41067..f5f8edc 100644 --- a/migrate/versioning/util/__init__.py +++ b/migrate/versioning/util/__init__.py @@ -6,6 +6,7 @@ from decorator import decorator from pkg_resources import EntryPoint from sqlalchemy import create_engine +from sqlalchemy.engine import Engine from migrate.versioning import exceptions from migrate.versioning.util.keyedinstance import KeyedInstance @@ -84,18 +85,18 @@ def catch_known_errors(f, *a, **kw): except exceptions.PathFoundError, e: raise exceptions.KnownError("The path %s already exists" % e.args[0]) -def construct_engine(url, **opts): +def construct_engine(engine, **opts): """.. versionadded:: 0.5.4 Constructs and returns SQLAlchemy engine. Currently, there are 2 ways to pass create_engine options to :mod:`migrate.versioning.api` functions: - :param url: connection string + :param engine: connection string or a existing engine :param engine_dict: python dictionary of options to pass to `create_engine` :param engine_arg_*: keyword parameters to pass to `create_engine` (evaluated with :func:`migrate.versioning.util.guess_obj_type`) :type engine_dict: dict - :type url: string + :type engine: string or Engine instance :type engine_arg_*: string :returns: SQLAlchemy Engine @@ -104,7 +105,11 @@ def construct_engine(url, **opts): keyword parameters override ``engine_dict`` values. """ - + if isinstance(engine, Engine): + return engine + elif not isinstance(engine, basestring): + raise ValueError("you need to pass either an existing engine or a database uri") + # get options for create_engine if opts.get('engine_dict') and isinstance(opts['engine_dict'], dict): kwargs = opts['engine_dict'] @@ -124,4 +129,4 @@ def construct_engine(url, **opts): if key.startswith('engine_arg_'): kwargs[key[11:]] = guess_obj_type(value) - return create_engine(url, **kwargs) + return create_engine(engine, **kwargs) diff --git a/test/versioning/test_util.py b/test/versioning/test_util.py index e131fe6..a3d4834 100644 --- a/test/versioning/test_util.py +++ b/test/versioning/test_util.py @@ -3,6 +3,8 @@ import os +from sqlalchemy import * + from test import fixture from migrate.versioning.util import * @@ -24,6 +26,11 @@ class TestUtil(fixture.Pathed): engine = construct_engine(url, engine_dict={'assert_unicode': True}) self.assertTrue(engine.dialect.assert_unicode) + # engine parameter + engine_orig = create_engine('sqlite://') + engine = construct_engine(engine_orig) + self.assertEqual(engine, engine_orig) + # test precedance engine = construct_engine(url, engine_dict={'assert_unicode': False}, engine_arg_assert_unicode=True)