From 2380151db9093b551dae8963c26851728320661b Mon Sep 17 00:00:00 2001 From: Robert DeRose Date: Mon, 28 Mar 2016 13:27:01 -0400 Subject: [PATCH 1/2] Support SQLAlchemy default in-memory SQLite URL SQLAlchemy's documentation states if you want to create an in-memory database you can provide a URL of `sqlite://` and that `:memory` is implied. The `database_exists` and `create_database` function did not handle this use-case. --- conftest.py | 5 +++++ sqlalchemy_utils/functions/database.py | 10 ++++++++-- tests/functions/test_database.py | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/conftest.py b/conftest.py index c5abb4c..0f3ea13 100644 --- a/conftest.py +++ b/conftest.py @@ -67,6 +67,11 @@ def sqlite_memory_dsn(): return 'sqlite:///:memory:' +@pytest.fixture +def sqlite_none_database_dsn(): + return 'sqlite://' + + @pytest.fixture def sqlite_file_dsn(): return 'sqlite:///{0}.db'.format(db_name) diff --git a/sqlalchemy_utils/functions/database.py b/sqlalchemy_utils/functions/database.py index 5b4bb30..20ffc9e 100644 --- a/sqlalchemy_utils/functions/database.py +++ b/sqlalchemy_utils/functions/database.py @@ -466,7 +466,12 @@ def database_exists(url): return bool(engine.execute(text).scalar()) elif engine.dialect.name == 'sqlite': - return database == ':memory:' or os.path.exists(database) + if database: + return database == ':memory:' or os.path.exists(database) + else: + # The default SQLAlchemy database is in memory, + # and :memory is not required, thus we should support that use-case + return True else: text = 'SELECT 1' @@ -538,7 +543,8 @@ def create_database(url, encoding='utf8', template=None): engine.execute(text) elif engine.dialect.name == 'sqlite' and database != ':memory:': - open(database, 'w').close() + if database: + open(database, 'w').close() else: text = 'CREATE DATABASE {0}'.format(quote(engine, database)) diff --git a/tests/functions/test_database.py b/tests/functions/test_database.py index 8d76942..9ddf73b 100644 --- a/tests/functions/test_database.py +++ b/tests/functions/test_database.py @@ -27,6 +27,12 @@ class TestDatabaseSQLiteMemory(object): assert database_exists(dsn) +@pytest.mark.usefixture('sqlite_none_database_dsn') +class TestDatabaseSQLiteMemoryNoDatabaseString(object): + def test_exists_memory_none_database(self, sqlite_none_database_dsn): + assert database_exists(sqlite_none_database_dsn) + + @pytest.mark.usefixtures('sqlite_file_dsn') class TestDatabaseSQLiteFile(DatabaseTest): pass From cbefac0904b0a77d60143e3f7c92c1a52b41893f Mon Sep 17 00:00:00 2001 From: Robert DeRose Date: Mon, 28 Mar 2016 13:44:25 -0400 Subject: [PATCH 2/2] Fix drop_database for SQLite The `drop_database` incorrectly reference the url.database value after it was set to `None`. It has been corrected to referrence `database` like the rest of the database types. --- sqlalchemy_utils/functions/database.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sqlalchemy_utils/functions/database.py b/sqlalchemy_utils/functions/database.py index 20ffc9e..6557563 100644 --- a/sqlalchemy_utils/functions/database.py +++ b/sqlalchemy_utils/functions/database.py @@ -575,8 +575,9 @@ def drop_database(url): engine = sa.create_engine(url) - if engine.dialect.name == 'sqlite' and url.database != ':memory:': - os.remove(url.database) + if engine.dialect.name == 'sqlite' and database != ':memory:': + if database: + os.remove(database) elif engine.dialect.name == 'postgresql' and engine.driver == 'psycopg2': from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT