fix(zot): match the models to Zotero's migrated schema

The Zotero app in the zotero container migrated its database (userdata
130): clientVersion on items, collections, libraries and savedSearches
(INT NOT NULL DEFAULT 0); nullable *Normalized text columns on creators,
tags, itemDataValues and itemAnnotations; savedSearchConditions lost
`required`; fulltextWords and fulltextItemWords are gone. The live-DB
schema tests failed on every full-suite commit.

New fields default to what the DB fills in when a column is omitted, so
inserts behave as before. The two models for dropped tables are removed.
This commit is contained in:
kert
2026-10-29 15:01:42 -04:00
parent d584b7f00d
commit 69548f4d44
8 changed files with 12 additions and 24 deletions

View File

@@ -68,6 +68,8 @@ class ItemAnnotations(SQLTable):
sortIndex: str | None = None
position: str | None = None
isExternal: int | None = None
textNormalized: str | None = None
commentNormalized: str | None = None
class RetractedItems(SQLTable):

View File

@@ -24,6 +24,7 @@ class Collections(SQLTable):
key: str
version: int = 0
synced: int = 0
clientVersion: int = 0
class CollectionItems(SQLTable):

View File

@@ -32,6 +32,7 @@ class Libraries(SQLTable):
lastSync: int = 0
archived: int = 0
isAdmin: int = 0
clientVersion: int = 0
class Items(SQLTable):
@@ -48,6 +49,7 @@ class Items(SQLTable):
key: str
version: int = 0
synced: int = 0
clientVersion: int = 0
class ItemTypes(SQLTable):

View File

@@ -21,6 +21,8 @@ class Creators(SQLTable):
firstName: str | None = None
lastName: str | None = None
fieldMode: int | None = None
firstNameNormalized: str | None = None
lastNameNormalized: str | None = None
class CreatorTypes(SQLTable):

View File

@@ -70,6 +70,7 @@ class ItemDataValues(SQLTable):
valueID: int | None = None
value: str | int | float | None = None
valueNormalized: str | None = None
class ItemTypeFields(SQLTable):

View File

@@ -5,9 +5,7 @@ from __future__ import annotations
from conf.table_base import SQLTable
__all__ = [
"FulltextWords",
"FulltextItems",
"FulltextItemWords",
"SavedSearches",
"SavedSearchConditions",
"FileTypes",
@@ -16,15 +14,6 @@ __all__ = [
]
class FulltextWords(SQLTable):
"""Zotero table ``fulltextWords`` (98,514 rows in host DB)."""
__tablename__ = "fulltextWords"
wordID: int | None = None
word: str | None = None
class FulltextItems(SQLTable):
"""Zotero table ``fulltextItems`` (2,083 rows in host DB)."""
@@ -39,15 +28,6 @@ class FulltextItems(SQLTable):
synced: int = 0
class FulltextItemWords(SQLTable):
"""Zotero table ``fulltextItemWords`` (2,048,235 rows in host DB)."""
__tablename__ = "fulltextItemWords"
wordID: int | None = None
itemID: int | None = None
class SavedSearches(SQLTable):
"""Zotero table ``savedSearches`` (3 rows in host DB)."""
@@ -60,6 +40,7 @@ class SavedSearches(SQLTable):
key: str
version: int = 0
synced: int = 0
clientVersion: int = 0
class SavedSearchConditions(SQLTable):
@@ -72,7 +53,6 @@ class SavedSearchConditions(SQLTable):
condition: str
operator: str | None = None
value: str | None = None
required: str | int | float | None = None
class FileTypes(SQLTable):

View File

@@ -17,6 +17,7 @@ class Tags(SQLTable):
tagID: int | None = None
name: str
nameNormalized: str | None = None
class ItemTags(SQLTable):

View File

@@ -62,9 +62,8 @@ class TestImports:
assert issubclass(ItemAnnotations, SQLTable)
def test_search(self):
from zot.table.search import FulltextItems, FulltextWords, SavedSearches
from zot.table.search import FulltextItems, SavedSearches
assert issubclass(FulltextWords, SQLTable)
assert issubclass(FulltextItems, SQLTable)
assert issubclass(SavedSearches, SQLTable)
@@ -87,7 +86,7 @@ class TestImports:
and issubclass(getattr(zt, name), SQLTable)
and getattr(zt, name) is not SQLTable
]
assert len(models) == 61
assert len(models) == 59
# ── Model correctness ───────────────────────────────────────────────