fix identification legacy table
All checks were successful
Deploy Plattform-Core / test (push) Successful in 43s
Deploy Plattform-Core / deploy (push) Successful in 4s

This commit is contained in:
ValueOn AG 2026-05-25 15:28:38 +02:00
parent 9719a22581
commit ac85c8e3dc
2 changed files with 17 additions and 18 deletions

View file

@ -799,12 +799,16 @@ def _jsonSafe(v):
def _discoverLegacyTables(dbFilter: Optional[str] = None) -> List[dict]: def _discoverLegacyTables(dbFilter: Optional[str] = None) -> List[dict]:
"""Find tables that exist in the DB but have no entry in MODEL_REGISTRY. """Find tables that exist in the DB but have no entry in MODEL_REGISTRY.
A table is legacy if its name does NOT match any PowerOnModel class.
Tables that exist in multiple DBs (shared-table pattern) are NOT flagged
as legacy -- the connector creates them wherever code writes that model.
Returns a list of dicts: {db, table, rowCount, sizeBytes}. Returns a list of dicts: {db, table, rowCount, sizeBytes}.
""" """
from modules.datamodels.datamodelBase import MODEL_REGISTRY from modules.datamodels.datamodelBase import MODEL_REGISTRY
from modules.shared.fkRegistry import _buildTableToDbMap from modules.shared.fkRegistry import _ensureModelsLoaded
tableToDb = _buildTableToDbMap() _ensureModelsLoaded()
registeredDbs = getRegisteredDatabases() registeredDbs = getRegisteredDatabases()
results: List[dict] = [] results: List[dict] = []
@ -831,11 +835,7 @@ def _discoverLegacyTables(dbFilter: Optional[str] = None) -> List[dict]:
""") """)
for row in cur.fetchall(): for row in cur.fetchall():
tblName = row["table_name"] tblName = row["table_name"]
inRegistry = ( if tblName not in MODEL_REGISTRY:
tblName in MODEL_REGISTRY
and tableToDb.get(tblName) == dbName
)
if not inRegistry:
results.append({ results.append({
"db": dbName, "db": dbName,
"table": tblName, "table": tblName,
@ -855,14 +855,10 @@ def _dropLegacyTable(dbName: str, tableName: str) -> dict:
Raises ValueError if the table is model-backed (safety guard). Raises ValueError if the table is model-backed (safety guard).
""" """
from modules.datamodels.datamodelBase import MODEL_REGISTRY from modules.datamodels.datamodelBase import MODEL_REGISTRY
from modules.shared.fkRegistry import _buildTableToDbMap from modules.shared.fkRegistry import _ensureModelsLoaded
tableToDb = _buildTableToDbMap() _ensureModelsLoaded()
inRegistry = ( if tableName in MODEL_REGISTRY:
tableName in MODEL_REGISTRY
and tableToDb.get(tableName) == dbName
)
if inRegistry:
raise ValueError( raise ValueError(
f"Table '{dbName}.{tableName}' is backed by a Pydantic model and cannot be dropped via legacy cleanup." f"Table '{dbName}.{tableName}' is backed by a Pydantic model and cannot be dropped via legacy cleanup."
) )

View file

@ -21,7 +21,7 @@ import psycopg2.extras
from modules.shared.configuration import APP_CONFIG from modules.shared.configuration import APP_CONFIG
from modules.shared.dbRegistry import getRegisteredDatabases from modules.shared.dbRegistry import getRegisteredDatabases
from modules.shared.fkRegistry import _buildTableToDbMap, getFkRelationships from modules.shared.fkRegistry import getFkRelationships
from modules.datamodels.datamodelBase import MODEL_REGISTRY from modules.datamodels.datamodelBase import MODEL_REGISTRY
from modules.system.databaseHealth import _getConnection, _jsonSafe from modules.system.databaseHealth import _getConnection, _jsonSafe
@ -120,15 +120,18 @@ def _exportDatabases(databases: List[str]) -> dict:
def _getModelTablesForDb(dbName: str, physicalTables: List[str]) -> List[str]: def _getModelTablesForDb(dbName: str, physicalTables: List[str]) -> List[str]:
"""Return only those physical tables that have a matching Pydantic model """Return only those physical tables that have a matching Pydantic model
registered in MODEL_REGISTRY and mapped to *dbName*. registered in MODEL_REGISTRY.
Tables without a Pydantic class (legacy / orphan tables) are excluded Tables without a Pydantic class (legacy / orphan tables) are excluded
from export so the backup contains only model-backed data. from export so the backup contains only model-backed data.
Note: the same model can exist in multiple databases (shared-table
pattern), so we only check membership in MODEL_REGISTRY, not the
DB mapping.
""" """
tableToDb = _buildTableToDbMap()
return sorted( return sorted(
t for t in physicalTables t for t in physicalTables
if t in MODEL_REGISTRY and tableToDb.get(t) == dbName if t in MODEL_REGISTRY
) )