Skip to content

Commit b5d0080

Browse files
committed
Handle db.table(table_name).insert({}), closes #759
1 parent 401fb69 commit b5d0080

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

sqlite_utils/db.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3179,6 +3179,20 @@ def build_insert_queries_and_params(
31793179
return a list of ``(sql, parameters)`` 2-tuples which, when executed in
31803180
order, perform the desired INSERT / UPSERT / REPLACE operation.
31813181
"""
3182+
# Dict-mode insert({}) has no explicit columns; SQLite spells that as
3183+
# DEFAULT VALUES. List mode with no columns is a different input shape.
3184+
if not list_mode and not all_columns:
3185+
or_clause = ""
3186+
if replace:
3187+
or_clause = " OR REPLACE"
3188+
elif ignore:
3189+
or_clause = " OR IGNORE"
3190+
sql = (
3191+
f"INSERT{or_clause} INTO {quote_identifier(self.name)} "
3192+
"DEFAULT VALUES"
3193+
)
3194+
return [(sql, []) for _ in chunk]
3195+
31823196
if hash_id_columns and hash_id is None:
31833197
hash_id = "id"
31843198

@@ -3603,7 +3617,11 @@ def insert_all(
36033617
assert (
36043618
num_columns <= SQLITE_MAX_VARS
36053619
), "Rows can have a maximum of {} columns".format(SQLITE_MAX_VARS)
3606-
batch_size = max(1, min(batch_size, SQLITE_MAX_VARS // num_columns))
3620+
batch_size = (
3621+
1
3622+
if num_columns == 0
3623+
else max(1, min(batch_size, SQLITE_MAX_VARS // num_columns))
3624+
)
36073625
self.last_rowid = None
36083626
self.last_pk = None
36093627
if truncate and self.exists():

tests/test_default_value.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,24 @@ def test_quote_default_value(fresh_db, column_def, initial_value, expected_value
3131
assert expected_value == fresh_db.quote_default_value(
3232
fresh_db["foo"].columns[0].default_value
3333
)
34+
35+
36+
def test_insert_empty_record_uses_default_values(fresh_db):
37+
fresh_db.execute("""
38+
CREATE TABLE has_defaults (
39+
id INTEGER PRIMARY KEY,
40+
name TEXT,
41+
timestamp TEXT DEFAULT CURRENT_TIMESTAMP,
42+
is_active INTEGER NOT NULL DEFAULT 1
43+
)
44+
""")
45+
46+
table = fresh_db["has_defaults"]
47+
table.insert({})
48+
49+
rows = list(table.rows)
50+
assert len(rows) == 1
51+
assert rows[0]["id"] == 1
52+
assert rows[0]["name"] is None
53+
assert rows[0]["timestamp"] is not None
54+
assert rows[0]["is_active"] == 1

0 commit comments

Comments
 (0)