pytest-django
pytest-django copied to clipboard
Live server error with sqlite3
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
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
Needs to be adjusted for Django 2.2+ I think, ref: https://github.com/django/django/commit/76990cbbda5d93fda560c8a5ab019860f7efaab7.
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?
See https://github.com/pytest-dev/pytest-django/pull/793 for a fix.
@cleder Have you tried #793?
Yes switching to this branch fixed it for me
I encountered this behavior in one of my projects. Interestingly, I have another project with same configs - and in that one live_server works.
Looks like the commit hasn't been merged so this should still be open.
I hit this problem today. Can I help get this sorted?
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.