From 7a9b264170baa29cafcbc593c73c31838f53dc24 Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Mon, 19 Jan 2026 16:25:04 +0100
Subject: [PATCH] fixed transactions
---
.../migration_export_20260119_085558.json | 1221 -----------------
tool_db_export_migration.py | 268 +++-
2 files changed, 264 insertions(+), 1225 deletions(-)
delete mode 100644 local/backup/migration_export_20260119_085558.json
diff --git a/local/backup/migration_export_20260119_085558.json b/local/backup/migration_export_20260119_085558.json
deleted file mode 100644
index 50cc9e5a..00000000
--- a/local/backup/migration_export_20260119_085558.json
+++ /dev/null
@@ -1,1221 +0,0 @@
-{
- "meta": {
- "exportedAt": "2026-01-19T07:55:59.185004Z",
- "exportedFrom": "Development Instance Patrick",
- "databaseName": "poweron_app",
- "version": "1.0",
- "tableCount": 6,
- "excludedTables": [
- "_system"
- ],
- "includesMeta": false,
- "totalRecords": 107
- },
- "tables": {
- "AccessRule": [
- {
- "id": "90990e75-ac45-4986-9c09-f299f198d2b3",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": null,
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "a9536849-a53b-458d-bab8-77a2a3ac2747",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": null,
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "n"
- },
- {
- "id": "54870935-d5a1-41b7-b088-30f70b4dc835",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": null,
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "a3743435-1015-4bd1-a256-4f91eda9f544",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": null,
- "view": 1,
- "read": "g",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "3e7b79b5-a68a-41b5-9e7f-f8159a310ed3",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Mandate",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "e7e8818c-04ed-473a-b1da-c7095f98f99e",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Mandate",
- "view": 0,
- "read": "n",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "61714126-2822-48cd-bbb5-175c141b2c0b",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Mandate",
- "view": 0,
- "read": "n",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "0ae9dcb8-302a-44cb-b777-1f9d26af7190",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Mandate",
- "view": 0,
- "read": "n",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "2ab27800-df9d-4307-aee3-d99064fbab5d",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "UserInDB",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "279c6538-401a-4cd3-a36a-d1399f8bd2e4",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "UserInDB",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "4ab1abbe-abf1-4510-8ba1-4afbb37b1fd1",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "UserInDB",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "m",
- "delete": "n"
- },
- {
- "id": "86c384a7-a2b5-4207-9e62-42cc50a2d20b",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "UserInDB",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "542af362-50c8-4e19-af21-5db2e0b8733e",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "UserConnection",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "8e356f1c-134d-4115-962e-0d0b7b71cf65",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "UserConnection",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "061b7a09-1003-4250-9524-64d648135467",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "UserConnection",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "89704bf9-d742-4149-a1e2-dcaaba9957c9",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "UserConnection",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "d296b5fb-48c3-4351-aa84-70ec1593369e",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "DataNeutraliserConfig",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "6ac892f8-69b6-4c2f-b18c-f5d58f8c95d9",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "DataNeutraliserConfig",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "defc2070-098f-44e2-9c59-264189730cc7",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "DataNeutraliserConfig",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "5927b71b-51f7-4671-a91b-f4f300af04f7",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "DataNeutraliserConfig",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "5a1907e7-6772-4b3f-9d34-6b847db3c14c",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "DataNeutralizerAttributes",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "c4eac0f8-e9d2-4064-80bd-a4e9c9e68686",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "DataNeutralizerAttributes",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "77a76ccf-91bb-4348-9caf-912b2bd7fe02",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "DataNeutralizerAttributes",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "d059cf52-8c56-4273-80f9-e7b8b40ebb4b",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "DataNeutralizerAttributes",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "0ca0ed8b-9327-43ff-b7b5-dc5870fb09c2",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "ChatWorkflow",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "a72168c5-bf33-43ef-a708-fd40e8feb6ba",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "ChatWorkflow",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "9c80b57b-d2ed-4309-9e87-62a98fe144d0",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "ChatWorkflow",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "4e534940-33cc-43ac-b859-9360a2e60cf1",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "ChatWorkflow",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "b0b3e37e-ea48-471e-95f6-b8e1e62ad09b",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Prompt",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "0f0f4c89-2aa5-4755-aeea-562bd020593d",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Prompt",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "0185dcc1-3560-4255-9840-8ab5db8042f8",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Prompt",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "c9c87948-21ce-47f4-8040-c02a0917aeb2",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Prompt",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "9e5f6dd5-c7a7-4a22-a1d6-82d4c68630a0",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Projekt",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "852f4f77-dac7-46de-8136-ebc46344101e",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Projekt",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "61710630-3c71-4adf-a997-b9e61d06fc00",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Projekt",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "158789bd-7f26-4d88-a27e-6ce11b3d94f9",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Projekt",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "c96b8b90-df7b-49ea-8ec9-0754c6179561",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Parzelle",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "cdb610f9-21c6-4e8d-b9b6-d4a44f372ad6",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Parzelle",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "6d3ff830-ae8f-4447-89a8-eaa8f8c4ecc7",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Parzelle",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "7791781c-810a-43ac-a5ce-d84a3584e5f4",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Parzelle",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "f49cd1cb-bdcd-4a9a-92fb-205078a3acba",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Dokument",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "44d5455e-a17b-4b6d-a426-21565fe1cef7",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Dokument",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "b2b58648-a555-4135-a038-84218a279437",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Dokument",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "073195c6-01bc-40f9-9896-f3c10ebce288",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Dokument",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "ba537ef0-239b-456d-b354-dec2c9d921ed",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Gemeinde",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "3d66cd04-f4e6-43f8-ab77-c31a87730096",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Gemeinde",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "bcc52c15-b41c-4a97-8e13-10035dd22202",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Gemeinde",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "844c7c02-dcc8-43a4-8eb5-f8ec198f50fd",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Gemeinde",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "15c1c76d-b8f7-40d2-8027-5ffdf6c96e28",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Kanton",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "b73379ef-3dbf-4118-b6f2-473f3c1c52e7",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Kanton",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "afc14c03-e953-4186-a923-4a12d3c6a312",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Kanton",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "c49ee8f3-f295-465d-be92-9bf46ee259e0",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Kanton",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "fcadb856-46f4-4ff0-85eb-67df3891c25d",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "Land",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "4a4e52ad-4ee3-4044-9e14-e0d797356139",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "Land",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "297ae474-ee2d-42f0-af09-eaa8b48d9684",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "Land",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "a567d373-00be-4c7e-b25e-deb6b10b57a3",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "Land",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "8f961779-1790-4cad-bebc-9b9bc436a29c",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "TrusteeOrganisation",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "81be065a-9ec6-4713-9fca-f5087cb9c3ee",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "TrusteeOrganisation",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "1fe2a920-0f9d-4c33-9288-4381af8c523e",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "TrusteeOrganisation",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "e99b39eb-ed55-4d08-a5d5-c3cf4645c312",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "TrusteeOrganisation",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "a54eed2a-e269-4884-ac2f-c09990f9b3d2",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "TrusteeRole",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "2bd073ca-30c3-43e0-8ea1-d77241053e7c",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "TrusteeRole",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "557ba1d5-2be0-43ee-a842-d0e74b45df41",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "TrusteeRole",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "81b46bcc-6cc3-40e0-9d82-f3a5bcc23b53",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "TrusteeRole",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "f3a58145-8986-42a7-bce4-eab0a1fa0962",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "TrusteeAccess",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "31d2a772-ed6b-447b-aa95-16a160d39601",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "TrusteeAccess",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "8a373342-8b8b-4a64-afd4-9f3ae8071d28",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "TrusteeAccess",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "b7a501e1-793f-47b6-b20c-1bfa61531cee",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "TrusteeAccess",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "0e67e101-5ce6-40fb-a783-104eebe29f92",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "TrusteeContract",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "23005b91-dc46-4bbe-a690-6c4568484858",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "TrusteeContract",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "aec6753b-cd7d-4ec8-8fa6-b9d007eb3657",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "TrusteeContract",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "31bf3c95-1012-4d61-91fc-36e4e3b832ec",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "TrusteeContract",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "17edb067-e62e-489a-842b-adbe4588aec0",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "TrusteeDocument",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "981e57b7-d813-4d67-9cf9-73576cc2affb",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "TrusteeDocument",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "3078980e-e8f2-44f0-b172-4a4c877b1b14",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "TrusteeDocument",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "f25efabc-e861-4cba-ad9c-6c8886f99ae5",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "TrusteeDocument",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "178c1dc4-7879-4a98-bbdd-54c1c55500c2",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "TrusteePosition",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "bbf02493-5ba2-4c0d-83b7-2a1c20e41108",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "TrusteePosition",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "7183b536-9a8a-4c2e-b6f4-4f69cc8a50b4",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "TrusteePosition",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "309130ca-254d-45b0-8629-47fe6a391a34",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "TrusteePosition",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "240fdaa4-75df-47a4-b33e-bce2e09dc741",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "TrusteePositionDocument",
- "view": 1,
- "read": "a",
- "create": "a",
- "update": "a",
- "delete": "a"
- },
- {
- "id": "528ba11a-824d-477a-ae2f-aa453fdea2f2",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "TrusteePositionDocument",
- "view": 1,
- "read": "g",
- "create": "g",
- "update": "g",
- "delete": "g"
- },
- {
- "id": "e3efeb99-eeb2-4450-85a4-f4261449a9ea",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "TrusteePositionDocument",
- "view": 1,
- "read": "m",
- "create": "m",
- "update": "m",
- "delete": "m"
- },
- {
- "id": "ca4bf93c-311c-4d2b-8b6e-9bd879ff5cde",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "TrusteePositionDocument",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "186bc21d-eb17-4d4a-ae4e-20725768befb",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "DATA",
- "item": "AuthEvent",
- "view": 1,
- "read": "a",
- "create": "n",
- "update": "n",
- "delete": "a"
- },
- {
- "id": "73d6eaa4-c1d1-4bfb-a2d6-a1772f9fd31c",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "DATA",
- "item": "AuthEvent",
- "view": 1,
- "read": "a",
- "create": "n",
- "update": "n",
- "delete": "a"
- },
- {
- "id": "2dce96a0-9a30-4d83-8544-29b60b7e8199",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "DATA",
- "item": "AuthEvent",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "91b2e3ef-7472-41b0-81ef-7e891ce7d183",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "DATA",
- "item": "AuthEvent",
- "view": 1,
- "read": "m",
- "create": "n",
- "update": "n",
- "delete": "n"
- },
- {
- "id": "5bf4d7af-d8e9-4ca0-a9d1-c4cdd6a8b2a8",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "UI",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- },
- {
- "id": "37999b49-c13c-44a1-a94e-41477d2e2e29",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "UI",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- },
- {
- "id": "b7af378c-0da9-4554-ab9e-3e4d5130778b",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "UI",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- },
- {
- "id": "d0c5bc55-d6e7-40c2-8bab-b7df13836712",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "UI",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- },
- {
- "id": "96827d13-bb10-4341-9615-03b940e4eab1",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "context": "RESOURCE",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- },
- {
- "id": "c052f46c-07b7-447b-885d-15803f615b6a",
- "roleId": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "context": "RESOURCE",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- },
- {
- "id": "91213ddd-9490-4f9f-928a-5f7c87bb6e05",
- "roleId": "bc22885c-5354-463e-a3fe-480941e016df",
- "context": "RESOURCE",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- },
- {
- "id": "58abcdc0-c8ba-435c-b01e-7b9c52581251",
- "roleId": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "context": "RESOURCE",
- "item": null,
- "view": 1,
- "read": null,
- "create": null,
- "update": null,
- "delete": null
- }
- ],
- "Mandate": [
- {
- "id": "e439ce2b-a8c2-4684-8c5f-70df493b82a1",
- "name": "Root",
- "enabled": 1
- }
- ],
- "Role": [
- {
- "id": "4564beaf-f07d-420f-a8af-d46dff0ba3b3",
- "roleLabel": "sysadmin",
- "description": {
- "en": "System Administrator - Full access to all system resources",
- "fr": "Administrateur système - Accès complet à toutes les ressources",
- "ge": null,
- "it": null
- },
- "mandateId": null,
- "featureInstanceId": null,
- "featureCode": null,
- "isSystemRole": 1
- },
- {
- "id": "9d7af325-2dc9-451f-88d1-090dc06de3db",
- "roleLabel": "admin",
- "description": {
- "en": "Administrator - Manage users and resources within mandate scope",
- "fr": "Administrateur - Gérer les utilisateurs et ressources dans le périmètre du mandat",
- "ge": null,
- "it": null
- },
- "mandateId": null,
- "featureInstanceId": null,
- "featureCode": null,
- "isSystemRole": 1
- },
- {
- "id": "bc22885c-5354-463e-a3fe-480941e016df",
- "roleLabel": "user",
- "description": {
- "en": "User - Standard user with access to own records",
- "fr": "Utilisateur - Utilisateur standard avec accès à ses propres enregistrements",
- "ge": null,
- "it": null
- },
- "mandateId": null,
- "featureInstanceId": null,
- "featureCode": null,
- "isSystemRole": 1
- },
- {
- "id": "95a88cf7-8a2a-42b2-b136-168966ad86b5",
- "roleLabel": "viewer",
- "description": {
- "en": "Viewer - Read-only access to group records",
- "fr": "Visualiseur - Accès en lecture seule aux enregistrements du groupe",
- "ge": null,
- "it": null
- },
- "mandateId": null,
- "featureInstanceId": null,
- "featureCode": null,
- "isSystemRole": 1
- }
- ],
- "UserInDB": [
- {
- "id": "3876d530-29d8-451d-a2fc-92af5cb2b817",
- "username": "admin",
- "email": "admin@example.com",
- "fullName": "Administrator",
- "language": "en",
- "enabled": 1,
- "isSysAdmin": 1,
- "roleLabels": [
- "sysadmin"
- ],
- "authenticationAuthority": "local",
- "mandateId": "e439ce2b-a8c2-4684-8c5f-70df493b82a1",
- "hashedPassword": "$argon2id$v=19$m=65536,t=3,p=4$Sumds1bqvZfyPseYs/YeYw$eiRcnO7J+ebit2oV6Ndqaer2ZIgPErTC9q2riRpiiwA",
- "resetToken": null,
- "resetTokenExpires": null
- },
- {
- "id": "805dcd6a-ac87-48c4-a1f0-987d8aa4a64b",
- "username": "event",
- "email": "event@example.com",
- "fullName": "Event",
- "language": "en",
- "enabled": 1,
- "isSysAdmin": 1,
- "roleLabels": [
- "sysadmin"
- ],
- "authenticationAuthority": "local",
- "mandateId": "e439ce2b-a8c2-4684-8c5f-70df493b82a1",
- "hashedPassword": "$argon2id$v=19$m=65536,t=3,p=4$BoDwnlNq7d3b2ztnrPWecw$ICkAaTjE/R39CJ7MryLmfmeEX5m4N/6S3HaDfOZuOBM",
- "resetToken": null,
- "resetTokenExpires": null
- }
- ],
- "UserMandate": [
- {
- "id": "70f9e733-7297-4afe-8784-9f7c730de3c4",
- "userId": "3876d530-29d8-451d-a2fc-92af5cb2b817",
- "mandateId": "e439ce2b-a8c2-4684-8c5f-70df493b82a1",
- "enabled": 1
- },
- {
- "id": "412ba93d-2abe-4916-8a80-bec4672c0baf",
- "userId": "805dcd6a-ac87-48c4-a1f0-987d8aa4a64b",
- "mandateId": "e439ce2b-a8c2-4684-8c5f-70df493b82a1",
- "enabled": 1
- }
- ],
- "UserMandateRole": [
- {
- "id": "cff2dd70-4dd6-4028-a384-7b0e8578f9dc",
- "userMandateId": "70f9e733-7297-4afe-8784-9f7c730de3c4",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3"
- },
- {
- "id": "54232df1-b559-44bb-8a51-adbd82818d94",
- "userMandateId": "412ba93d-2abe-4916-8a80-bec4672c0baf",
- "roleId": "4564beaf-f07d-420f-a8af-d46dff0ba3b3"
- }
- ]
- },
- "summary": {
- "AccessRule": {
- "recordCount": 96
- },
- "Mandate": {
- "recordCount": 1
- },
- "Role": {
- "recordCount": 4
- },
- "UserInDB": {
- "recordCount": 2
- },
- "UserMandate": {
- "recordCount": 2
- },
- "UserMandateRole": {
- "recordCount": 2
- }
- }
-}
\ No newline at end of file
diff --git a/tool_db_export_migration.py b/tool_db_export_migration.py
index 09aa2f8f..6c93370a 100644
--- a/tool_db_export_migration.py
+++ b/tool_db_export_migration.py
@@ -5,6 +5,8 @@ Datenbank Export-Tool für Migration.
Dieses Script exportiert alle Daten aus ALLEN PowerOn PostgreSQL-Datenbanken
in eine JSON-Datei, die als Migrationsdatensatz verwendet werden kann.
+Zusätzlich wird eine separate JSON-Datei mit nur den Strukturen (ohne Daten)
+erstellt: _structure.json
Datenbanken:
- poweron_app (User, Mandate, RBAC, Features, etc.)
@@ -18,6 +20,7 @@ Verwendung:
Optionen:
--output, -o Pfad zur Ausgabedatei (Standard: migration_export_.json)
+ Die Struktur-Datei wird automatisch als _structure.json erstellt
--pretty, -p JSON formatiert ausgeben (für bessere Lesbarkeit)
--exclude Komma-getrennte Liste von Tabellen, die ausgeschlossen werden sollen
--include-meta System-Metadaten (_createdAt, _modifiedAt, etc.) beibehalten
@@ -150,6 +153,8 @@ def _getDbConnection(dbDatabase: str):
password=dbPassword,
cursor_factory=psycopg2.extras.RealDictCursor
)
+ # Autocommit muss VOR set_client_encoding gesetzt werden, um Transaction-Konflikte zu vermeiden
+ conn.autocommit = True
conn.set_client_encoding('UTF8')
return conn
except Exception as e:
@@ -205,6 +210,222 @@ def _getTableRowCount(conn, tableName: str) -> int:
return result["count"] if result else 0
+def _getTableStructure(conn, tableName: str) -> Dict[str, Any]:
+ """Holt die Struktur einer Tabelle (Spalten, Constraints, Indizes) ohne Daten."""
+ structure = {
+ "columns": [],
+ "primaryKeys": [],
+ "foreignKeys": [],
+ "uniqueConstraints": [],
+ "indexes": [],
+ "checkConstraints": []
+ }
+
+ # Connection hat bereits autocommit = True, daher keine Transaction-Probleme
+ with conn.cursor() as cursor:
+ # Spalten-Informationen
+ cursor.execute("""
+ SELECT
+ column_name,
+ data_type,
+ character_maximum_length,
+ numeric_precision,
+ numeric_scale,
+ is_nullable,
+ column_default,
+ udt_name
+ FROM information_schema.columns
+ WHERE table_schema = 'public'
+ AND table_name = %s
+ ORDER BY ordinal_position
+ """, (tableName,))
+
+ for row in cursor.fetchall():
+ colInfo = {
+ "name": row["column_name"],
+ "type": row["data_type"],
+ "udtName": row["udt_name"],
+ "nullable": row["is_nullable"] == "YES",
+ "default": row["column_default"]
+ }
+
+ if row["character_maximum_length"]:
+ colInfo["maxLength"] = row["character_maximum_length"]
+ if row["numeric_precision"]:
+ colInfo["precision"] = row["numeric_precision"]
+ if row["numeric_scale"]:
+ colInfo["scale"] = row["numeric_scale"]
+
+ structure["columns"].append(colInfo)
+
+ # Primary Keys
+ cursor.execute("""
+ SELECT
+ kcu.column_name
+ FROM information_schema.table_constraints tc
+ JOIN information_schema.key_column_usage kcu
+ ON tc.constraint_name = kcu.constraint_name
+ WHERE tc.table_schema = 'public'
+ AND tc.table_name = %s
+ AND tc.constraint_type = 'PRIMARY KEY'
+ ORDER BY kcu.ordinal_position
+ """, (tableName,))
+
+ structure["primaryKeys"] = [row["column_name"] for row in cursor.fetchall()]
+
+ # Foreign Keys
+ cursor.execute("""
+ SELECT
+ kcu.column_name,
+ ccu.table_name AS foreign_table_name,
+ ccu.column_name AS foreign_column_name,
+ tc.constraint_name
+ FROM information_schema.table_constraints AS tc
+ JOIN information_schema.key_column_usage AS kcu
+ ON tc.constraint_name = kcu.constraint_name
+ JOIN information_schema.constraint_column_usage AS ccu
+ ON ccu.constraint_name = tc.constraint_name
+ WHERE tc.constraint_type = 'FOREIGN KEY'
+ AND tc.table_schema = 'public'
+ AND tc.table_name = %s
+ """, (tableName,))
+
+ for row in cursor.fetchall():
+ structure["foreignKeys"].append({
+ "column": row["column_name"],
+ "referencesTable": row["foreign_table_name"],
+ "referencesColumn": row["foreign_column_name"],
+ "constraintName": row["constraint_name"]
+ })
+
+ # Unique Constraints - FIX: Tabellen-Aliase verwenden um ambiguous columns zu vermeiden
+ cursor.execute("""
+ SELECT
+ kcu.column_name,
+ tc.constraint_name
+ FROM information_schema.table_constraints tc
+ JOIN information_schema.key_column_usage kcu
+ ON tc.constraint_name = kcu.constraint_name
+ AND tc.table_schema = kcu.table_schema
+ AND tc.table_name = kcu.table_name
+ WHERE tc.table_schema = 'public'
+ AND tc.table_name = %s
+ AND tc.constraint_type = 'UNIQUE'
+ ORDER BY kcu.ordinal_position
+ """, (tableName,))
+
+ uniqueGroups = {}
+ for row in cursor.fetchall():
+ constraintName = row["constraint_name"]
+ if constraintName not in uniqueGroups:
+ uniqueGroups[constraintName] = []
+ uniqueGroups[constraintName].append(row["column_name"])
+
+ structure["uniqueConstraints"] = [
+ {"columns": cols, "constraintName": name}
+ for name, cols in uniqueGroups.items()
+ ]
+
+ # Indizes (ohne Primary Key und Unique Constraints)
+ cursor.execute("""
+ SELECT
+ i.relname AS index_name,
+ a.attname AS column_name,
+ ix.indisunique AS is_unique
+ FROM pg_class t
+ JOIN pg_index ix ON t.oid = ix.indrelid
+ JOIN pg_class i ON i.oid = ix.indexrelid
+ JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
+ WHERE t.relkind = 'r'
+ AND t.relname = %s
+ AND NOT ix.indisprimary
+ ORDER BY i.relname, a.attnum
+ """, (tableName,))
+
+ indexGroups = {}
+ for row in cursor.fetchall():
+ indexName = row["index_name"]
+ if indexName not in indexGroups:
+ indexGroups[indexName] = {
+ "name": indexName,
+ "columns": [],
+ "unique": row["is_unique"]
+ }
+ indexGroups[indexName]["columns"].append(row["column_name"])
+
+ structure["indexes"] = list(indexGroups.values())
+
+ # Check Constraints - FIX: Tabellen-Aliase verwenden
+ cursor.execute("""
+ SELECT
+ cc.constraint_name,
+ cc.check_clause
+ FROM information_schema.check_constraints cc
+ JOIN information_schema.constraint_column_usage ccu
+ ON cc.constraint_name = ccu.constraint_name
+ WHERE ccu.table_schema = 'public'
+ AND ccu.table_name = %s
+ """, (tableName,))
+
+ for row in cursor.fetchall():
+ structure["checkConstraints"].append({
+ "constraintName": row["constraint_name"],
+ "checkClause": row["check_clause"]
+ })
+
+ return structure
+
+
+def _exportSingleDatabaseStructure(
+ dbDatabase: str,
+ excludeTables: List[str]
+) -> Optional[Dict[str, Any]]:
+ """Exportiert nur die Struktur einer einzelnen Datenbank (ohne Daten)."""
+ conn = _getDbConnection(dbDatabase)
+
+ if conn is None:
+ return None
+
+ try:
+ allTables = _getTables(conn)
+
+ # System-Tabellen ausschliessen
+ systemTables = ["_system"]
+ tablesToExport = [
+ t for t in allTables
+ if t not in systemTables and t not in excludeTables
+ ]
+
+ dbExport = {
+ "tables": {},
+ "summary": {},
+ "tableCount": len(tablesToExport)
+ }
+
+ for tableName in tablesToExport:
+ try:
+ structure = _getTableStructure(conn, tableName)
+ dbExport["tables"][tableName] = structure
+ dbExport["summary"][tableName] = {
+ "columnCount": len(structure["columns"]),
+ "primaryKeyCount": len(structure["primaryKeys"]),
+ "foreignKeyCount": len(structure["foreignKeys"]),
+ "indexCount": len(structure["indexes"])
+ }
+
+ logger.info(f" {tableName}: {len(structure['columns'])} Spalten")
+
+ except Exception as e:
+ logger.error(f" Fehler bei Tabelle {tableName}: {e}")
+ dbExport["tables"][tableName] = {}
+ dbExport["summary"][tableName] = {"error": str(e)}
+
+ return dbExport
+
+ finally:
+ conn.close()
+
+
def _exportSingleDatabase(
dbDatabase: str,
excludeTables: List[str],
@@ -249,6 +470,7 @@ def _exportSingleDatabase(
logger.error(f" Fehler bei Tabelle {tableName}: {e}")
dbExport["tables"][tableName] = []
dbExport["summary"][tableName] = {"recordCount": 0, "error": str(e)}
+ # Bei autocommit = True ist kein rollback() notwendig
return dbExport
@@ -265,6 +487,7 @@ def exportDatabase(
) -> str:
"""
Exportiert alle Datenbanken in eine JSON-Datei.
+ Erstellt zusätzlich eine separate JSON-Datei mit nur den Strukturen (ohne Daten).
Args:
outputPath: Pfad zur Ausgabedatei (optional)
@@ -310,12 +533,31 @@ def exportDatabase(
"databases": {}
}
+ # Struktur-Export erstellen
+ structureData = {
+ "meta": {
+ "exportedAt": datetime.utcnow().isoformat() + "Z",
+ "exportedFrom": _getConfigValue("APP_ENV_LABEL", "unknown"),
+ "version": "1.0",
+ "databaseCount": 0,
+ "totalTables": 0,
+ "excludedTables": excludeTables,
+ "note": "Nur Strukturen, keine Daten"
+ },
+ "databases": {}
+ }
+
# Jede Datenbank exportieren
for dbName in databasesToExport:
logger.info(f"Exportiere Datenbank: {dbName}")
+ # Daten exportieren
dbExport = _exportSingleDatabase(dbName, excludeTables, includeMeta)
+ # Struktur exportieren
+ logger.info(f"Exportiere Struktur für Datenbank: {dbName}")
+ dbStructure = _exportSingleDatabaseStructure(dbName, excludeTables)
+
if dbExport is not None:
exportData["databases"][dbName] = dbExport
exportData["meta"]["databaseCount"] += 1
@@ -324,8 +566,13 @@ def exportDatabase(
logger.info(f" -> {dbExport['tableCount']} Tabellen, {dbExport['totalRecords']} Datensätze")
else:
logger.info(f" -> Übersprungen (existiert nicht)")
+
+ if dbStructure is not None:
+ structureData["databases"][dbName] = dbStructure
+ structureData["meta"]["databaseCount"] += 1
+ structureData["meta"]["totalTables"] += dbStructure["tableCount"]
- # JSON-Datei schreiben
+ # JSON-Datei mit Daten schreiben
logger.info(f"Schreibe Exportdatei: {outputPath}")
with open(outputPath, "w", encoding="utf-8") as f:
@@ -334,16 +581,29 @@ def exportDatabase(
else:
json.dump(exportData, f, ensure_ascii=False, default=str)
- # Dateigrösse berechnen
+ # JSON-Datei mit Strukturen schreiben
+ structurePath = outputPath.replace(".json", "_structure.json")
+ logger.info(f"Schreibe Struktur-Exportdatei: {structurePath}")
+
+ with open(structurePath, "w", encoding="utf-8") as f:
+ if prettyPrint:
+ json.dump(structureData, f, indent=2, ensure_ascii=False, default=str)
+ else:
+ json.dump(structureData, f, ensure_ascii=False, default=str)
+
+ # Dateigrössen berechnen
fileSize = os.path.getsize(outputPath)
fileSizeStr = _formatFileSize(fileSize)
+ structureFileSize = os.path.getsize(structurePath)
+ structureFileSizeStr = _formatFileSize(structureFileSize)
+
logger.info(f"Export abgeschlossen!")
logger.info(f" Datenbanken: {exportData['meta']['databaseCount']}")
logger.info(f" Tabellen: {exportData['meta']['totalTables']}")
logger.info(f" Datensätze: {exportData['meta']['totalRecords']}")
- logger.info(f" Dateigrösse: {fileSizeStr}")
- logger.info(f" Ausgabedatei: {outputPath}")
+ logger.info(f" Daten-Export: {fileSizeStr} - {outputPath}")
+ logger.info(f" Struktur-Export: {structureFileSizeStr} - {structurePath}")
return outputPath