summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Linville <aaron@linville.org>2023-08-17 18:06:25 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2024-02-16 12:59:19 +0100
commit7a05b8a2fac57e32a61726893d4601352c1d1c8d (patch)
tree186513f0f28bad17ced097853358e72609415ac5
parent66e47ac69a7e71cf32eee312d05668d8f1ba24bb (diff)
Fixed #24018 -- Allowed setting pragma options on SQLite.
-rw-r--r--AUTHORS1
-rw-r--r--django/db/backends/sqlite3/base.py6
-rw-r--r--docs/ref/databases.txt24
-rw-r--r--docs/releases/5.1.txt7
-rw-r--r--docs/spelling_wordlist1
-rw-r--r--tests/backends/sqlite/tests.py23
6 files changed, 62 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
index 6fef75cf43..945a017cf8 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,6 +6,7 @@ people who have submitted patches, reported bugs, added translations, helped
answer newbie questions, and generally made Django that much better:
Aaron Cannon <cannona@fireantproductions.com>
+ Aaron Linville <aaron@linville.org>
Aaron Swartz <http://www.aaronsw.com/>
Aaron T. Myers <atmyers@gmail.com>
Abeer Upadhyay <ab.esquarer@gmail.com>
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 8e17ea3d44..c7cf947800 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -187,6 +187,9 @@ class DatabaseWrapper(BaseDatabaseWrapper):
f"{allowed_transaction_modes}, or None."
)
self.transaction_mode = transaction_mode.upper() if transaction_mode else None
+
+ init_command = kwargs.pop("init_command", "")
+ self.init_commands = init_command.split(";")
return kwargs
def get_database_version(self):
@@ -201,6 +204,9 @@ class DatabaseWrapper(BaseDatabaseWrapper):
# The macOS bundled SQLite defaults legacy_alter_table ON, which
# prevents atomic table renames.
conn.execute("PRAGMA legacy_alter_table = OFF")
+ for init_command in self.init_commands:
+ if init_command := init_command.strip():
+ conn.execute(init_command)
return conn
def create_cursor(self, name=None):
diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt
index d853647730..1bc787671e 100644
--- a/docs/ref/databases.txt
+++ b/docs/ref/databases.txt
@@ -941,6 +941,30 @@ To enable the JSON1 extension you can follow the instruction on
.. _JSON1 extension: https://www.sqlite.org/json1.html
.. _the wiki page: https://code.djangoproject.com/wiki/JSON1Extension
+.. _sqlite-init-command:
+
+Setting pragma options
+----------------------
+
+.. versionadded:: 5.1
+
+`Pragma options`_ can be set upon connection by using the ``init_command`` in
+the :setting:`OPTIONS` part of your database configuration in
+:setting:`DATABASES`. The example below shows how to enable extra durability of
+synchronous writes and change the ``cache_size``::
+
+ DATABASES = {
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ # ...
+ "OPTIONS": {
+ "init_command": "PRAGMA synchronous=3; PRAGMA cache_size=2000;",
+ },
+ }
+ }
+
+.. _Pragma options: https://www.sqlite.org/pragma.html
+
.. _oracle-notes:
Oracle notes
diff --git a/docs/releases/5.1.txt b/docs/releases/5.1.txt
index 94c342e8a0..e288bab20c 100644
--- a/docs/releases/5.1.txt
+++ b/docs/releases/5.1.txt
@@ -146,6 +146,13 @@ CSRF
* ...
+Database backends
+~~~~~~~~~~~~~~~~~
+
+* ``"init_command"`` option is now supported in :setting:`OPTIONS` on SQLite
+ to allow specifying :ref:`pragma options <sqlite-init-command>` to set upon
+ connection.
+
Decorators
~~~~~~~~~~
diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist
index 5828b24253..1044cd80eb 100644
--- a/docs/spelling_wordlist
+++ b/docs/spelling_wordlist
@@ -361,6 +361,7 @@ postfix
postgis
postgres
postgresql
+pragma
pre
precisions
precomputation
diff --git a/tests/backends/sqlite/tests.py b/tests/backends/sqlite/tests.py
index 42fee432f9..91dd83f134 100644
--- a/tests/backends/sqlite/tests.py
+++ b/tests/backends/sqlite/tests.py
@@ -116,6 +116,29 @@ class Tests(TestCase):
connection.check_database_version_supported()
self.assertTrue(mocked_get_database_version.called)
+ def test_init_command(self):
+ settings_dict = {
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": ":memory:",
+ "OPTIONS": {
+ "init_command": "PRAGMA synchronous=3; PRAGMA cache_size=2000;",
+ },
+ }
+ }
+ connections = ConnectionHandler(settings_dict)
+ connections["default"].ensure_connection()
+ try:
+ with connections["default"].cursor() as cursor:
+ cursor.execute("PRAGMA synchronous")
+ value = cursor.fetchone()[0]
+ self.assertEqual(value, 3)
+ cursor.execute("PRAGMA cache_size")
+ value = cursor.fetchone()[0]
+ self.assertEqual(value, 2000)
+ finally:
+ connections["default"].close()
+
@unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
@isolate_apps("backends")