From 6b5e386469248d35aa05197a8bf262329020f08a Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Mon, 25 May 2026 16:30:27 +0200
Subject: [PATCH] db fixed import
---
modules/system/databaseMigration.py | 51 ++++++++++++++++++-----------
1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/modules/system/databaseMigration.py b/modules/system/databaseMigration.py
index 4739b8ff..d255bde2 100644
--- a/modules/system/databaseMigration.py
+++ b/modules/system/databaseMigration.py
@@ -742,18 +742,18 @@ def _importSingleDb(payload: dict, dbName: str, mode: str, protectedIds: List[st
conn = _getConnection(dbName)
try:
- conn.autocommit = False
existingTables = set(_listTables(conn))
- # Pre-create missing tables so FK ordering can discover them
+ # Ensure all import tables exist (create missing ones from export schema)
for tableName, rows in tables.items():
- if tableName in excluded or not isinstance(rows, list):
+ if tableName in excluded or not isinstance(rows, list) or not rows:
continue
if tableName not in existingTables:
+ conn.autocommit = True
_createTableFromExport(conn, tableName, rows)
- conn.commit()
conn.autocommit = False
existingTables.add(tableName)
+ logger.info("Pre-created missing table %s.%s", dbName, tableName)
# Build importable table list and sort by FK dependencies
importable = [t for t in tables
@@ -771,29 +771,40 @@ def _importSingleDb(payload: dict, dbName: str, mode: str, protectedIds: List[st
# Phase 1 (replace only): DELETE children first (reverse topological order)
if mode == "replace":
for tableName in reversed(importOrder):
- _deleteNonProtected(conn, tableName, protectedIdSet)
+ try:
+ conn.autocommit = False
+ _deleteNonProtected(conn, tableName, protectedIdSet)
+ conn.commit()
+ except Exception as e:
+ conn.rollback()
+ warnings.append(f"DELETE from {dbName}.{tableName} failed: {e}")
+ logger.warning("DELETE from %s.%s failed: %s", dbName, tableName, e)
# Phase 2: INSERT parents first (topological order)
for tableName in importOrder:
- rows = tables[tableName]
- physicalCols = _getPhysicalColumns(conn, tableName)
- if not physicalCols:
- continue
-
- filteredRows = []
- for row in rows:
- if _isProtectedRow(tableName, row):
+ try:
+ conn.autocommit = False
+ rows = tables[tableName]
+ physicalCols = _getPhysicalColumns(conn, tableName)
+ if not physicalCols:
continue
- if row.get("id") and str(row["id"]) in protectedIdSet:
- continue
- filteredRows.append(row)
- insertedCount = _insertRows(conn, tableName, filteredRows, physicalCols, mode)
- dbResult[tableName] = insertedCount
+ filteredRows = []
+ for row in rows:
+ if _isProtectedRow(tableName, row):
+ continue
+ if row.get("id") and str(row["id"]) in protectedIdSet:
+ continue
+ filteredRows.append(row)
- conn.commit()
+ insertedCount = _insertRows(conn, tableName, filteredRows, physicalCols, mode)
+ conn.commit()
+ dbResult[tableName] = insertedCount
+ except Exception as e:
+ conn.rollback()
+ warnings.append(f"INSERT into {dbName}.{tableName} failed: {e}")
+ logger.warning("INSERT into %s.%s failed: %s", dbName, tableName, e)
except Exception as e:
- conn.rollback()
logger.error("Import failed for database %s: %s", dbName, e)
return {"database": dbName, "tables": {}, "recordCount": 0,
"warnings": [f"Import fuer '{dbName}' fehlgeschlagen: {e}"]}