feat(llm): index_state.fingerprint + index_docket_state migrations (refs #615)
This commit is contained in:
@@ -21,10 +21,27 @@ CREATE TABLE IF NOT EXISTS index_state (
|
|||||||
content_hash TEXT NOT NULL,
|
content_hash TEXT NOT NULL,
|
||||||
chunk_count INTEGER NOT NULL DEFAULT 0,
|
chunk_count INTEGER NOT NULL DEFAULT 0,
|
||||||
indexed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
indexed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
fingerprint TEXT NOT NULL DEFAULT '',
|
||||||
PRIMARY KEY (item_key, collection)
|
PRIMARY KEY (item_key, collection)
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Existing databases predate the column.
|
||||||
|
INDEX_STATE_ALTER = "ALTER TABLE index_state ADD COLUMN IF NOT EXISTS fingerprint TEXT NOT NULL DEFAULT ''"
|
||||||
|
|
||||||
|
# A sealed docket that was fully indexed under a given seal: the iterator
|
||||||
|
# does not even list its items until the seal changes (unseal/reseal
|
||||||
|
# writes a new sealed_at in bib, which no longer matches).
|
||||||
|
INDEX_DOCKET_STATE_DDL = """
|
||||||
|
CREATE TABLE IF NOT EXISTS index_docket_state (
|
||||||
|
collection TEXT NOT NULL,
|
||||||
|
docket TEXT NOT NULL,
|
||||||
|
sealed_at TEXT NOT NULL,
|
||||||
|
indexed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
PRIMARY KEY (collection, docket)
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
# langchain-postgres creates langchain_pg_embedding with an untyped vector
|
# langchain-postgres creates langchain_pg_embedding with an untyped vector
|
||||||
# column; HNSW needs a typed one. ALTER is a no-op when already typed.
|
# column; HNSW needs a typed one. ALTER is a no-op when already typed.
|
||||||
_HNSW_DDL = [
|
_HNSW_DDL = [
|
||||||
@@ -35,9 +52,11 @@ _HNSW_DDL = [
|
|||||||
|
|
||||||
|
|
||||||
def migrate(engine: Engine) -> None:
|
def migrate(engine: Engine) -> None:
|
||||||
"""Create llm-owned tables. Safe to run on every start."""
|
"""Create llm-owned tables/columns. Safe to run on every start."""
|
||||||
with engine.begin() as conn:
|
with engine.begin() as conn:
|
||||||
conn.execute(text(INDEX_STATE_DDL))
|
conn.execute(text(INDEX_STATE_DDL))
|
||||||
|
conn.execute(text(INDEX_STATE_ALTER))
|
||||||
|
conn.execute(text(INDEX_DOCKET_STATE_DDL))
|
||||||
|
|
||||||
|
|
||||||
def ensure_hnsw(engine: Engine, dim: int) -> None:
|
def ensure_hnsw(engine: Engine, dim: int) -> None:
|
||||||
|
|||||||
@@ -24,3 +24,20 @@ class TestDdl:
|
|||||||
executed = " ".join(str(call.args[0]) for call in conn.execute.call_args_list)
|
executed = " ".join(str(call.args[0]) for call in conn.execute.call_args_list)
|
||||||
assert "vector(768)" in executed
|
assert "vector(768)" in executed
|
||||||
assert "USING hnsw" in executed
|
assert "USING hnsw" in executed
|
||||||
|
|
||||||
|
def test_fingerprint_column_and_docket_state(self):
|
||||||
|
assert "fingerprint" in migrate.INDEX_STATE_DDL
|
||||||
|
assert "ADD COLUMN IF NOT EXISTS fingerprint" in migrate.INDEX_STATE_ALTER
|
||||||
|
assert (
|
||||||
|
"CREATE TABLE IF NOT EXISTS index_docket_state"
|
||||||
|
in migrate.INDEX_DOCKET_STATE_DDL
|
||||||
|
)
|
||||||
|
assert "PRIMARY KEY (collection, docket)" in migrate.INDEX_DOCKET_STATE_DDL
|
||||||
|
|
||||||
|
def test_migrate_runs_alter_and_docket_state(self):
|
||||||
|
engine = MagicMock()
|
||||||
|
conn = engine.begin.return_value.__enter__.return_value
|
||||||
|
migrate.migrate(engine)
|
||||||
|
executed = " ".join(str(call.args[0]) for call in conn.execute.call_args_list)
|
||||||
|
assert "ADD COLUMN IF NOT EXISTS fingerprint" in executed
|
||||||
|
assert "index_docket_state" in executed
|
||||||
|
|||||||
Reference in New Issue
Block a user