mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-10-08 02:17:08 +02:00
.reset_counts() method and reset-counts command, closes #219
This commit is contained in:
parent
b4f09146d3
commit
0d2a47eab9
4 changed files with 56 additions and 2 deletions
|
|
@ -1074,6 +1074,10 @@ The ``sqlite-utils enable-counts`` command can be used to configure these trigge
|
||||||
# Configure triggers just for specific tables
|
# Configure triggers just for specific tables
|
||||||
$ sqlite-utils enable-counts mydb.db table1 table2
|
$ sqlite-utils enable-counts mydb.db table1 table2
|
||||||
|
|
||||||
|
If the ``_counts`` table ever becomes out-of-sync with the actual table counts you can repair it using the ``reset-counts`` command::
|
||||||
|
|
||||||
|
$ sqlite-utils reset-counts mydb.db
|
||||||
|
|
||||||
.. _cli_vacuum:
|
.. _cli_vacuum:
|
||||||
|
|
||||||
Vacuum
|
Vacuum
|
||||||
|
|
|
||||||
|
|
@ -1768,6 +1768,12 @@ If the property is ``True`` any calls to the ``table.count`` property will first
|
||||||
|
|
||||||
Calling the ``.enable_counts()`` method on a database or table object will set ``use_counts_table`` to ``True`` for the lifetime of that database object.
|
Calling the ``.enable_counts()`` method on a database or table object will set ``use_counts_table`` to ``True`` for the lifetime of that database object.
|
||||||
|
|
||||||
|
If the ``_counts`` table ever becomes out-of-sync with the actual table counts you can repair it using the ``.reset_counts()`` method:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
db.reset_counts()
|
||||||
|
|
||||||
Creating indexes
|
Creating indexes
|
||||||
================
|
================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,17 @@ class Database:
|
||||||
except OperationalError:
|
except OperationalError:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
def reset_counts(self):
|
||||||
|
tables = [table for table in self.tables if table.has_counts_triggers]
|
||||||
|
with self.conn:
|
||||||
|
self._ensure_counts_table()
|
||||||
|
counts_table = self[self._counts_table_name]
|
||||||
|
counts_table.delete_where()
|
||||||
|
counts_table.insert_all(
|
||||||
|
{"table": table.name, "count": table.execute_count()}
|
||||||
|
for table in tables
|
||||||
|
)
|
||||||
|
|
||||||
def execute_returning_dicts(self, sql, params=None):
|
def execute_returning_dicts(self, sql, params=None):
|
||||||
cursor = self.execute(sql, params or tuple())
|
cursor = self.execute(sql, params or tuple())
|
||||||
keys = [d[0] for d in cursor.description]
|
keys = [d[0] for d in cursor.description]
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,10 @@ def test_enable_counts_all_tables(fresh_db):
|
||||||
def counts_db_path(tmpdir):
|
def counts_db_path(tmpdir):
|
||||||
path = str(tmpdir / "test.db")
|
path = str(tmpdir / "test.db")
|
||||||
db = Database(path)
|
db = Database(path)
|
||||||
db["foo"].insert({"name": "Cleo"})
|
db["foo"].insert({"name": "bar"})
|
||||||
db["bar"].insert({"name": "Cleo"})
|
db["bar"].insert({"name": "bar"})
|
||||||
|
db["bar"].insert({"name": "bar"})
|
||||||
|
db["baz"].insert({"name": "bar"})
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -79,6 +81,8 @@ def counts_db_path(tmpdir):
|
||||||
"foo_counts_delete",
|
"foo_counts_delete",
|
||||||
"bar_counts_insert",
|
"bar_counts_insert",
|
||||||
"bar_counts_delete",
|
"bar_counts_delete",
|
||||||
|
"baz_counts_insert",
|
||||||
|
"baz_counts_delete",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
@ -121,11 +125,40 @@ def test_uses_counts_after_enable_counts(counts_db_path):
|
||||||
("select name from sqlite_master where type = 'view'", None),
|
("select name from sqlite_master where type = 'view'", None),
|
||||||
("select name from sqlite_master where type = 'view'", None),
|
("select name from sqlite_master where type = 'view'", None),
|
||||||
("select name from sqlite_master where type = 'view'", None),
|
("select name from sqlite_master where type = 'view'", None),
|
||||||
|
("select name from sqlite_master where type = 'view'", None),
|
||||||
("select sql from sqlite_master where name = ?", ("foo",)),
|
("select sql from sqlite_master where name = ?", ("foo",)),
|
||||||
("SELECT quote(:value)", {"value": "foo"}),
|
("SELECT quote(:value)", {"value": "foo"}),
|
||||||
("select sql from sqlite_master where name = ?", ("bar",)),
|
("select sql from sqlite_master where name = ?", ("bar",)),
|
||||||
("SELECT quote(:value)", {"value": "bar"}),
|
("SELECT quote(:value)", {"value": "bar"}),
|
||||||
|
("select sql from sqlite_master where name = ?", ("baz",)),
|
||||||
|
("SELECT quote(:value)", {"value": "baz"}),
|
||||||
("select sql from sqlite_master where name = ?", ("_counts",)),
|
("select sql from sqlite_master where name = ?", ("_counts",)),
|
||||||
("select name from sqlite_master where type = 'view'", None),
|
("select name from sqlite_master where type = 'view'", None),
|
||||||
("select [table], count from _counts where [table] in (?)", ["foo"]),
|
("select [table], count from _counts where [table] in (?)", ["foo"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_counts(counts_db_path):
|
||||||
|
db = Database(counts_db_path)
|
||||||
|
db["foo"].enable_counts()
|
||||||
|
db["bar"].enable_counts()
|
||||||
|
assert db.cached_counts() == {"foo": 1, "bar": 2}
|
||||||
|
# Corrupt the value
|
||||||
|
db["_counts"].update("foo", {"count": 3})
|
||||||
|
assert db.cached_counts() == {"foo": 3, "bar": 2}
|
||||||
|
assert db["foo"].count == 3
|
||||||
|
# Reset them
|
||||||
|
db.reset_counts()
|
||||||
|
assert db.cached_counts() == {"foo": 1, "bar": 2}
|
||||||
|
assert db["foo"].count == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_counts_cli(counts_db_path):
|
||||||
|
db = Database(counts_db_path)
|
||||||
|
db["foo"].enable_counts()
|
||||||
|
db["bar"].enable_counts()
|
||||||
|
assert db.cached_counts() == {"foo": 1, "bar": 2}
|
||||||
|
db["_counts"].update("foo", {"count": 3})
|
||||||
|
result = CliRunner().invoke(cli.cli, ["reset-counts", counts_db_path])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert db.cached_counts() == {"foo": 1, "bar": 2}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue