mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-27 20:34:12 +02:00
table.rebuild_fts() method, refs #155
This commit is contained in:
parent
deb2eb013f
commit
4c0f79398f
3 changed files with 52 additions and 0 deletions
|
|
@ -1213,6 +1213,21 @@ To remove the FTS tables and triggers you created, use the ``disable_fts()`` tab
|
||||||
|
|
||||||
dogs.disable_fts()
|
dogs.disable_fts()
|
||||||
|
|
||||||
|
Rebuilding a full-text search table
|
||||||
|
===================================
|
||||||
|
|
||||||
|
You can rebuild a table using the ``table.rebuild_fts()`` method. This is useful for if the table configuration changes or the indexed data has become corrupted in some way.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
dogs.rebuild_fts()
|
||||||
|
|
||||||
|
This method can be called on a table that has been configured for full-text search - ``dogs`` in this instance - or directly on a ``_fts`` table:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
db["dogs_fts"].rebuild_fts()
|
||||||
|
|
||||||
Optimizing a full-text search table
|
Optimizing a full-text search table
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -905,6 +905,17 @@ class Table(Queryable):
|
||||||
for trigger_name in trigger_names:
|
for trigger_name in trigger_names:
|
||||||
self.db.execute("DROP TRIGGER IF EXISTS [{}]".format(trigger_name))
|
self.db.execute("DROP TRIGGER IF EXISTS [{}]".format(trigger_name))
|
||||||
|
|
||||||
|
def rebuild_fts(self):
|
||||||
|
fts_table = self.detect_fts()
|
||||||
|
if fts_table is None:
|
||||||
|
# Assume this is itself an FTS table
|
||||||
|
fts_table = self.name
|
||||||
|
self.db.execute(
|
||||||
|
"INSERT INTO [{table}]([{table}]) VALUES('rebuild');".format(
|
||||||
|
table=fts_table
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def detect_fts(self):
|
def detect_fts(self):
|
||||||
"Detect if table has a corresponding FTS virtual table and return it"
|
"Detect if table has a corresponding FTS virtual table and return it"
|
||||||
sql = (
|
sql = (
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
from sqlite_utils.utils import sqlite3
|
||||||
|
|
||||||
search_records = [
|
search_records = [
|
||||||
{
|
{
|
||||||
|
|
@ -173,3 +174,28 @@ def test_disable_fts(fresh_db, create_triggers):
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
)
|
)
|
||||||
assert ["searchable"] == fresh_db.table_names()
|
assert ["searchable"] == fresh_db.table_names()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("table_to_fix", ["searchable", "searchable_fts"])
|
||||||
|
def test_rebuild_fts(fresh_db, table_to_fix):
|
||||||
|
table = fresh_db["searchable"]
|
||||||
|
table.insert(search_records[0])
|
||||||
|
table.enable_fts(["text", "country"])
|
||||||
|
# Run a search
|
||||||
|
assert [("tanuki are running tricksters", "Japan", "foo")] == table.search("tanuki")
|
||||||
|
# Delete from searchable_fts_data
|
||||||
|
fresh_db["searchable_fts_data"].delete_where()
|
||||||
|
# This should have broken the index
|
||||||
|
with pytest.raises(sqlite3.DatabaseError):
|
||||||
|
table.search("tanuki")
|
||||||
|
# Running rebuild_fts() should fix it
|
||||||
|
fresh_db[table_to_fix].rebuild_fts()
|
||||||
|
assert [("tanuki are running tricksters", "Japan", "foo")] == table.search("tanuki")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("invalid_table", ["does_not_exist", "not_searchable"])
|
||||||
|
def test_rebuild_fts_invalid(fresh_db, invalid_table):
|
||||||
|
fresh_db["not_searchable"].insert({"foo": "bar"})
|
||||||
|
# Raise OperationalError on invalid table
|
||||||
|
with pytest.raises(sqlite3.OperationalError):
|
||||||
|
fresh_db[invalid_table].rebuild_fts()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue