analyze=True for insert_all/upsert_all, refs #378

This commit is contained in:
Simon Willison 2022-01-10 17:00:34 -08:00
commit 131ed27ab0
3 changed files with 28 additions and 2 deletions

View file

@ -638,8 +638,9 @@ The function can accept an iterator or generator of rows and will commit them ac
You can skip inserting any records that have a primary key that already exists using ``ignore=True``. This works with both ``.insert({...}, ignore=True)`` and ``.insert_all([...], ignore=True)``. You can skip inserting any records that have a primary key that already exists using ``ignore=True``. This works with both ``.insert({...}, ignore=True)`` and ``.insert_all([...], ignore=True)``.
You can delete all the existing rows in the table before inserting the new You can delete all the existing rows in the table before inserting the new records using ``truncate=True``. This is useful if you want to replace the data in the table.
records using ``truncate=True``. This is useful if you want to replace the data in the table.
Pass ``analyze=True`` to run ``ANALYZE`` against the table after inserting the new records.
.. _python_api_insert_replace: .. _python_api_insert_replace:

View file

@ -2575,10 +2575,13 @@ class Table(Queryable):
conversions=DEFAULT, conversions=DEFAULT,
columns=DEFAULT, columns=DEFAULT,
upsert=False, upsert=False,
analyze=False,
) -> "Table": ) -> "Table":
""" """
Like ``.insert()`` but takes a list of records and ensures that the table Like ``.insert()`` but takes a list of records and ensures that the table
that it creates (if table does not exist) has columns for ALL of that data. that it creates (if table does not exist) has columns for ALL of that data.
Use ``analyze=True`` to run ``ANALYZE`` after the insert has completed.
""" """
pk = self.value_or_default("pk", pk) pk = self.value_or_default("pk", pk)
foreign_keys = self.value_or_default("foreign_keys", foreign_keys) foreign_keys = self.value_or_default("foreign_keys", foreign_keys)
@ -2671,6 +2674,9 @@ class Table(Queryable):
ignore, ignore,
) )
if analyze:
self.analyze()
return self return self
def upsert( def upsert(
@ -2721,6 +2727,7 @@ class Table(Queryable):
extracts=DEFAULT, extracts=DEFAULT,
conversions=DEFAULT, conversions=DEFAULT,
columns=DEFAULT, columns=DEFAULT,
analyze=False,
) -> "Table": ) -> "Table":
""" """
Like ``.upsert()`` but can be applied to a list of records. Like ``.upsert()`` but can be applied to a list of records.
@ -2739,6 +2746,7 @@ class Table(Queryable):
conversions=conversions, conversions=conversions,
columns=columns, columns=columns,
upsert=True, upsert=True,
analyze=analyze,
) )
def add_missing_columns(self, records: Iterable[Dict[str, Any]]) -> "Table": def add_missing_columns(self, records: Iterable[Dict[str, Any]]) -> "Table":

View file

@ -1028,6 +1028,23 @@ def test_insert_all_single_column(fresh_db):
assert table.pks == ["name"] assert table.pks == ["name"]
@pytest.mark.parametrize("method_name", ("insert_all", "upsert_all"))
def test_insert_all_analyze(fresh_db, method_name):
table = fresh_db["table"]
table.insert_all([{"id": 1, "name": "Cleo"}], pk="id")
assert "sqlite_stat1" not in fresh_db.table_names()
table.create_index(["name"], analyze=True)
assert list(fresh_db["sqlite_stat1"].rows) == [
{"tbl": "table", "idx": "idx_table_name", "stat": "1 1"}
]
method = getattr(table, method_name)
method([{"id": 2, "name": "Suna"}], pk="id", analyze=True)
assert "sqlite_stat1" in fresh_db.table_names()
assert list(fresh_db["sqlite_stat1"].rows) == [
{"tbl": "table", "idx": "idx_table_name", "stat": "2 1"}
]
def test_create_with_a_null_column(fresh_db): def test_create_with_a_null_column(fresh_db):
record = {"name": "Name", "description": None} record = {"name": "Name", "description": None}
fresh_db["t"].insert(record) fresh_db["t"].insert(record)