]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Support SQLite WITHOUT ROWID tables 5686/head
authorSean Anderson <seanga2@gmail.com>
Sat, 7 Nov 2020 17:13:05 +0000 (12:13 -0500)
committerSean Anderson <seanga2@gmail.com>
Sat, 7 Nov 2020 19:35:27 +0000 (14:35 -0500)
This adds support for creating tables WITHOUT ROWID in the SQLite
dialect. WITHOUT ROWID tables were introduced in SQLite version 3.8.2
(2013-12-06). They do not use an implicit rowid column as the primary
key. This may result in space and performance savings for tables without
INTEGER primary keys and tables with composite primary keys. For more
information about this feature, see the sqlite documentation [1].

[1] https://www.sqlite.org/withoutrowid.html

Fixes: #5685
lib/sqlalchemy/dialects/sqlite/base.py
test/dialect/test_sqlite.py

index 5efd0d9c991edc3fd7dc32afd1ab24f65da2fd4f..eeeb172eeeb862add73d30d2803c11dead5c24d7 100644 (file)
@@ -583,6 +583,21 @@ or on a per-:class:`_engine.Engine` basis::
 When using the per-:class:`_engine.Engine` execution option, note that
 **Core and ORM queries that use UNION may not function properly**.
 
+SQLite-specific table options
+-----------------------------
+
+One option for CREATE TABLE is supported directly by the SQLite
+dialect in conjunction with the :class:`_schema.Table` construct:
+
+* ``WITHOUT ROWID``::
+
+    Table("some_table", metadata, ..., sqlite_with_rowid=False)
+
+.. seealso::
+
+    `SQLite CREATE TABLE options
+    <https://www.sqlite.org/lang_createtable.html>`_
+
 """  # noqa
 
 import datetime
@@ -1259,6 +1274,11 @@ class SQLiteDDLCompiler(compiler.DDLCompiler):
 
         return text
 
+    def post_create_table(self, table):
+        if table.dialect_options["sqlite"]["with_rowid"] is False:
+            return "\n WITHOUT ROWID"
+        return ""
+
 
 class SQLiteTypeCompiler(compiler.GenericTypeCompiler):
     def visit_large_binary(self, type_, **kw):
@@ -1466,7 +1486,13 @@ class SQLiteDialect(default.DefaultDialect):
     isolation_level = None
 
     construct_arguments = [
-        (sa_schema.Table, {"autoincrement": False}),
+        (
+            sa_schema.Table,
+            {
+                "autoincrement": False,
+                "with_rowid": True,
+            }
+        ),
         (sa_schema.Index, {"where": None}),
         (
             sa_schema.Column,
index 4f581433c5d9d35fad6bfea27047f016cf102eaf..26e8ad3a51f1aa3c88f78699555ac75f636aed1c 100644 (file)
@@ -1165,6 +1165,16 @@ class SQLTest(fixtures.TestBase, AssertsCompiledSQL):
             ),
         )
 
+    def test_create_table_without_rowid(self):
+        m = MetaData()
+        tbl = Table(
+            "atable", m, Column("id", Integer), sqlite_with_rowid=False
+        )
+        self.assert_compile(
+            schema.CreateTable(tbl),
+            "CREATE TABLE atable (id INTEGER) WITHOUT ROWID",
+        )
+
 
 class OnConflictDDLTest(fixtures.TestBase, AssertsCompiledSQL):