sqlite database table is locked on tests

可紊 提交于 2019-12-23 08:08:13

问题


I am trying to migrate an application from django 1.11.1 to django 2.0.1 Tests are set up to run with sqlite in memory database. But every test is failing, because sqlite3.OperationalError: database table is locked for every table. How can I find out why is it locked? Icreasing timeout setting does not help.

I am using LiveServerTestCase, so I suppose the tests must be running in a different thread than the in memory database, and it for some reason does not get shared.


回答1:


I hit this, too. The LiveServerTestCase is multi-threaded since this got merged.

It becomes a problem for me when my app under test issues multiple requests. Then, so my speculation, the LiveServer spawns threads to handle those requests. Those requests then cause a write to the SQLite db. That in turn does not like multiple writing threads.

Funnily enough, runserver knows about --nothreading. But such an option seems to be missing for the test server.

The following snippet brought me a single-threaded test server:

class LiveServerSingleThread(LiveServerThread):
    """Runs a single threaded server rather than multi threaded. Reverts https://github.com/django/django/pull/7832"""

    def _create_server(self):
        return WSGIServer((self.host, self.port), QuietWSGIRequestHandler, allow_reuse_address=False)


class LiveServerSingleThreadedTestCase(LiveServerTestCase):
    "A thin sub-class which only sets the single-threaded server as a class"
    server_thread_class = LiveServerSingleThread

Then, derive your test class from LiveServerSingleThreadedTestCase instead of LiveServerTestCase.




回答2:


It was caused by this django bug.




回答3:


Using a file-based database during testing fixes the "table is locked" error. To make Django use a file-based database, specify it's filename as test database name:

DATABASES = {
    'default': {
        ...
        'TEST': {
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3.test'),
       },
    }
}

I suppose that the timeout setting is ignored in case of in-memory database, see this comment for additional info.



来源:https://stackoverflow.com/questions/48353002/sqlite-database-table-is-locked-on-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!