It's been my experience that enabling this can dramatically improve
performance, especially under heavy writes. I've seen some write-heavy
operations go from a couple of minutes to a few seconds.
It can be enabled by executing the command:
PRAGMA journal_mode=wal;
which will return 'wal' on success.
If it fails to apply for any reason, it will return the mode it is in -
'delete' or 'memory'.
I propose to add JOURNAL_MODE as an option to the sqlite backend.
however, some quick tinkering shows that the sqlite backend doesn't ever
explicitly create the DB, so it's not immediately apparent how to detect
if/when this command should be issued.
I am still investigating.
--
Ticket URL: <https://code.djangoproject.com/ticket/24018>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* owner: nobody => funkybob
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:1>
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:2>
Comment (by tonnzor):
Any progress here?
We could add `init_command` to `OPTIONS` for sqlite backend like for
MySQL.
Then you would be able to use any PRAGMA we need:
{{{
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'OPTIONS': {
'init_command': 'PRAGMA journal_mode=wal;',
}
}
}
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:3>
Comment (by tonnzor):
As a workaround, you could use https://stackoverflow.com/a/6843199 (use
`connection_created` signal)
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:4>
* owner: Curtis Maloney => Aaron Linville
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:5>
* has_patch: 0 => 1
Comment:
https://github.com/django/django/pull/14824
I needed the ability to adjust some pragma settings associated with
caching but as Artem noted, this will work for any pragma setting.
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:6>
* needs_better_patch: 0 => 1
* needs_docs: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:7>
Comment (by Carlton Gibson):
Maybe allowing `PRAGMAS` to be set is a good idea, in general (e.g.
#31765) but the WAL setting is persistent:
> The persistence of WAL mode means that applications can be converted to
using SQLite in WAL mode without making any changes to the application
itself. One has merely to run "PRAGMA journal_mode=WAL;" on the database
file(s) using the command-line shell or other utility, then restart the
application. [https://sqlite.org/wal.html#persistence_of_wal_mode SQLite
Docs].
So narrowly, running that a single time is sufficient, and an entry in the
[https://docs.djangoproject.com/en/3.2/ref/databases/#sqlite-notes SQLite
notes] may be the quickest route forward (for this narrower issue).
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:8>
Comment (by Afonso Silva):
Based on the previous answers, a workaround for allowing `init_command`
similar to MySQL is to use a signal receiver for `connection_created`,
e.g.:
{{{#!python
from django.conf import settings
from django.db.backends.signals import connection_created
from django.dispatcher import receiver
@receiver(connection_created)
def init_command(sender, connection, **kwargs) -> None:
command = connection.settings_dict["OPTIONS"].get("init_command")
if connection.vendor == "sqlite" and command:
cursor = connection.cursor()
cursor.execute(command)
}}}
This way you could add `init_command` to your `settings.py`:
{{{#!python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'OPTIONS': {
'init_command': 'PRAGMA journal_mode=wal;'
}
}
}
}}}
I think having this natively in Django would be useful, is there any help
needed for the previous linked PR?
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:9>
Comment (by Aaron Linville):
Replying to [comment:9 Afonso Silva]:
> I think having this natively in Django would be useful, is there any
help needed for the previous linked PR?
I updated the PR and modified it with a more compelling example;
`synchronous=0` will not persist.
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:10>
@Aaron, are you still wanting to work on this? If so, if you fix the tests
you could update the flags on this issue so it goes back in the list of
tickets to be reviewed.
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:11>
Replying to [comment:11 bcail]:
> @Aaron, are you still wanting to work on this? If so, if you fix the
tests you could update the flags on this issue so it goes back in the list
of tickets to be reviewed.
Yes, I've rebased it on latest and fixed the tests I think (a couple are
still pending). Assume you mean uncheck the Needs doc and Patch needs
improvement?
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:12>
* cc: bcail (added)
Comment:
Yup, exactly - so it shows up on the
[https://code.djangoproject.com/query?status=!closed&needs_better_patch=0&needs_tests=0&needs_docs=0&has_patch=1&stage=Accepted&desc=1&order=changetime
Patch review page].
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:13>
* needs_better_patch: 1 => 0
* needs_docs: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:14>
* summary: Support journal_mode=WAL for sqlite => Support setting pragma
options for SQLite.
--
Ticket URL: <https://code.djangoproject.com/ticket/24018#comment:15>