Balzer-WaagenDaten/exporter.py

152 lines
5.1 KiB
Python

import os
import adodbapi
import pyodbc
from dotenv import load_dotenv
load_dotenv()
# Lokaler Pfad und SDF-Datei definieren
SDF_LOCAL_PFAD = os.getenv("SDF_LOCAL_PFAD")
sdf_file = os.path.join(SDF_LOCAL_PFAD, "App.sdf")
sdf_connection_str = (
"Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;"
f"Data Source={sdf_file};"
"Persist Security Info=False;"
)
# MSSQL-Verbindungszeichenfolge aus der .env
mssql_connection_str = os.getenv("MSSQL_CONNECTION_STR")
if not mssql_connection_str:
print("MSSQL_CONNECTION_STR nicht in der .env gefunden.")
exit(1)
# Die Liste der Tabellen aus deiner SDF-Datenbank
tables = [
"Addressee",
"ADR",
"AxlesArchive",
"CardEncoding",
"Carrier",
"Coeff",
"Conveyer",
"CustomerLDB",
"Fields",
"GeneralData",
"PDR",
"Plate",
"Product",
"RDR",
"RDR_LDB_Weighing",
"Reason",
"Supplier",
"Tare",
"TxWeighing",
"Weighing_LDB"
]
def get_pk_columns(mssql_cursor, table_name):
"""
Ermittelt die Primary-Key-Spalten für eine Tabelle in MSSQL.
"""
pk_query = """
SELECT KU.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
ON TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME
WHERE TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND KU.TABLE_NAME = ?
ORDER BY KU.ORDINAL_POSITION;
"""
mssql_cursor.execute(pk_query, (table_name,))
return [row[0] for row in mssql_cursor.fetchall()]
try:
# Verbindung zur SDF-Datenbank herstellen
sdf_conn = adodbapi.connect(sdf_connection_str)
sdf_cursor = sdf_conn.cursor()
# Verbindung zur MSSQL-Datenbank herstellen
mssql_conn = pyodbc.connect(mssql_connection_str)
mssql_cursor = mssql_conn.cursor()
for table_name in tables:
print(f"\nVerarbeite Tabelle: {table_name}")
# Spaltennamen ermitteln aus der SDF-Tabelle
sdf_cursor.execute(f"SELECT * FROM [{table_name}]")
columns = [col[0] for col in sdf_cursor.description]
print(f"Gefundene Spalten: {columns}")
# Ermittlung der Primary-Key-Spalten aus MSSQL (falls vorhanden)
pk_columns = get_pk_columns(mssql_cursor, table_name)
if pk_columns:
print(f"Primary Key Spalte(n) für {table_name}: {pk_columns}")
try:
pk_indices = [columns.index(pk) for pk in pk_columns]
except ValueError as ve:
print(f"Fehler bei der Ermittlung der PK-Indizes für {table_name}: {ve}")
pk_indices = []
else:
print(f"Kein Primary Key in MSSQL für {table_name} definiert.")
pk_indices = []
identity_insert = False
if table_name == "Weighing_LDB":
identity_insert = True
try:
mssql_cursor.execute(f"SET IDENTITY_INSERT {table_name} ON")
print(f"IDENTITY_INSERT für {table_name} aktiviert.")
except Exception as ie:
print(f"Fehler beim Aktivieren von IDENTITY_INSERT für {table_name}: {ie}")
# Daten aus der SDF-Tabelle auslesen
sdf_cursor.execute(f"SELECT * FROM [{table_name}]")
rows = sdf_cursor.fetchall()
print(f"{len(rows)} Datensätze gefunden.")
# Insert-Statement für MSSQL vorbereiten
placeholders = ", ".join("?" for _ in columns)
insert_sql = f"INSERT INTO {table_name} ({', '.join('[' + col + ']' for col in columns)}) VALUES ({placeholders})"
inserted = 0
skipped = 0
for row in rows:
# Falls ein Primary Key definiert ist, prüfen wir, ob der Datensatz bereits existiert
if pk_indices:
pk_values = tuple(row[i] for i in pk_indices)
pk_clause = " AND ".join(f"[{col}] = ?" for col in pk_columns)
select_pk_sql = f"SELECT COUNT(*) FROM {table_name} WHERE {pk_clause}"
mssql_cursor.execute(select_pk_sql, pk_values)
count = mssql_cursor.fetchone()[0]
if count > 0:
skipped += 1
continue # Datensatz existiert bereits -> überspringen
# Datensatz einfügen
try:
mssql_cursor.execute(insert_sql, *row)
inserted += 1
except Exception as ie:
print(f"Fehler beim Einfügen in Tabelle {table_name}: {ie}")
mssql_conn.commit()
print(f"Für Tabelle {table_name}: {inserted} Datensätze eingefügt, {skipped} übersprungen.")
# Falls IDENTITY_INSERT aktiviert wurde, wieder deaktivieren
if identity_insert:
try:
mssql_cursor.execute(f"SET IDENTITY_INSERT {table_name} OFF")
mssql_conn.commit()
print(f"IDENTITY_INSERT für {table_name} deaktiviert.")
except Exception as ie:
print(f"Fehler beim Deaktivieren von IDENTITY_INSERT für {table_name}: {ie}")
# Verbindungen schließen
sdf_cursor.close()
sdf_conn.close()
mssql_cursor.close()
mssql_conn.close()
except Exception as e:
print(f"Allgemeiner Fehler: {e}")