﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
25406	"_create_test_db hides errors like 'source database ""template1"" is being accessed by other users' with --keepdb"	Daniel Hahler	Mariusz Felisiak	"The _create_test_db method will hide errors like 'source database ""template1"" is being accessed by other users', and will assume that the test database exists already.

{{{
> …/pyenv/project/lib/python3.4/site-packages/psycopg2/__init__.py(165)connect()
    164     import ipdb; ipdb.set_trace()
--> 165     conn = _connect(dsn, connection_factory=connection_factory, async=async)
    166     if cursor_factory is not None:

ipdb> c
source database ""template1"" is being accessed by other users
DETAIL:  There are 3 other sessions using the database.

> …/pyenv/project/lib/python3.4/site-packages/django/db/backends/base/creation.py(458)_create_test_db()
    457                 # just return and skip it all.
--> 458                 if keepdb:
    459                     return test_database_name
}}}
Source reference: https://github.com/blueyed/django/blob/9e530b08d5858d7063d081b60ec86d24173e4df5/django/db/backends/base/creation.py#L146-L165

This will then result in an error when trying to connect to it, because it has not been created:

  psycopg2.OperationalError: FATAL:  database ""test_project"" does not exist


But instead the initial error should be displayed:

  source database ""template1"" is being accessed by other users
  DETAIL:  There are 3 other sessions using the database.


To reproduce this:

 - connect to the ""template1"" database
 - run Django tests

I think the SQL could use `CREATE DATABASE IF NOT EXISTS` (in case `IF NOT EXISTS`) is supported by all backends (maybe that needs to be subclassed then), and then would not assume that an Exception can be ignored with `keepdb`.

An even better way would be to check if it exists, instead of trying to create it.

With pytest-django we're using the following code:
{{{
def test_database_exists_from_previous_run(connection):
    # Try to open a cursor to the test database
    test_db_name = connection.creation._get_test_db_name()

    # When using a real SQLite backend (via TEST_NAME), check if the file
    # exists, because it gets created automatically.
    if connection.settings_dict['ENGINE'] == 'django.db.backends.sqlite3':
        if not os.path.exists(test_db_name):
            return False

    orig_db_name = connection.settings_dict['NAME']
    connection.settings_dict['NAME'] = test_db_name

    # With SQLite memory databases the db never exists.
    if connection.settings_dict['NAME'] == ':memory:':
        return False

    try:
        connection.cursor()
        return True
    except Exception:  # TODO: Be more discerning but still DB agnostic.
        return False
    finally:
        connection.close()
        connection.settings_dict['NAME'] = orig_db_name
}}}
(Source: https://github.com/blueyed/pytest_django/blob/93fca47feea39016dd93e657a9328450e9b6e891/pytest_django/db_reuse.py#L11-L35)"	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed		felisiak.mariusz@…	Ready for checkin	1	0	0	0	0	0
