pytest-django icon indicating copy to clipboard operation
pytest-django copied to clipboard

Live server error with sqlite3

Open cleder opened this issue 6 years ago • 10 comments
trafficstars

When using the live_server in an integration test fixture:

@pytest.fixture(scope='session', name='server_url')
def get_server_url(live_server, environment):
    """Start a django server to test against and return the url of the server."""
    yield live_server.url

the following error is generated:


self = <[AttributeError("'LiveServer' object has no attribute 'thread'") raised in repr()] LiveServer object at 0x80526a8d0>
addr = 'localhost'

    def __init__(self, addr):
        import django
        from django.db import connections
        from django.test.testcases import LiveServerThread
        from django.test.utils import modify_settings
    
        connections_override = {}
        for conn in connections.all():
            # If using in-memory sqlite databases, pass the connections to
            # the server thread.
            if (
                conn.settings_dict["ENGINE"] == "django.db.backends.sqlite3"
                and conn.settings_dict["NAME"] == ":memory:"
            ):
                # Explicitly enable thread-shareability for this connection
>               conn.allow_thread_sharing = True
E               AttributeError: can't set attribute

/home/goldeneagle/venv/lib/python3.7/site-packages/pytest_django/live_server_helper.py:27: AttributeError

cleder avatar Nov 18 '19 15:11 cleder

This may be hard to reproduce Environment: Python 3.7.5 on FreeBSD with py37-sqlite with pytest 4.5.0 and 5.2.4 Django 2.2.7

cleder avatar Nov 18 '19 15:11 cleder

Needs to be adjusted for Django 2.2+ I think, ref: https://github.com/django/django/commit/76990cbbda5d93fda560c8a5ab019860f7efaab7.

blueyed avatar Nov 18 '19 19:11 blueyed

I wonder why you hit the (apparently wrong) conn.settings_dict["NAME"] == ":memory:".. (this should check the TEST db name). Are you using an in-memory DB by default within your tests?

blueyed avatar Jan 05 '20 23:01 blueyed

See https://github.com/pytest-dev/pytest-django/pull/793 for a fix.

blueyed avatar Jan 05 '20 23:01 blueyed

@cleder Have you tried #793?

blueyed avatar Jan 06 '20 13:01 blueyed

Yes switching to this branch fixed it for me

cleder avatar Jan 07 '20 17:01 cleder

I encountered this behavior in one of my projects. Interestingly, I have another project with same configs - and in that one live_server works.

dekoza avatar Apr 29 '20 06:04 dekoza

Looks like the commit hasn't been merged so this should still be open.

bluetech avatar Oct 17 '20 12:10 bluetech

I hit this problem today. Can I help get this sorted?

boxed avatar Feb 19 '21 09:02 boxed

As a workaround, simply set your database name to file::memory:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': "file::memory:",
    },
}

The problem came from live_server_helper.py, in the LiveServer constructor:

        for conn in connections.all():
            # If using in-memory sqlite databases, pass the connections to
            # the server thread.
            if (
                conn.settings_dict["ENGINE"] == "django.db.backends.sqlite3"
                and conn.settings_dict["NAME"] == ":memory:"
            ):
                # Explicitly enable thread-shareability for this connection
               conn.allow_thread_sharing = True

As conn.settings_dict["NAME"] is compared to str :memory:, changing that value to something else will prevent from entering the if-block. So, the wrong statement wont be executed.

Since Django 2.2, allow_code_sharing is a read-only property of BaseDatabaseWrapper object (see https://github.com/django/django/blob/stable/2.2.x/django/db/backends/base/base.py#L520). It was previously a normal member (see https://github.com/django/django/blob/stable/2.1.x/django/db/backends/base/base.py#L83).

Hope one of the open pull request regarding this issue will be merged soon.

alorence avatar Nov 12 '21 09:11 alorence