diff --git a/.env b/.env index e69de29..995c1b9 100644 --- a/.env +++ b/.env @@ -0,0 +1,16 @@ +#### Auflistung der Variablen + +MSSQL_CONNECTION_STR="Driver={SQL Server};Server=172.17.1.25;Database=balzerwaagenpc;UID=sa;PWD=adm.3dfx12;" + +E_MAIL_ADDRESS="serfling@itdata-gera.de" +E_MAIL_ADDRESS_PASSWORD="" +E_MAIL_SMTP_SERVER="mail.itdata-gera.de" +E_MAIL_SMTP_SERVER_PORT="25" +E_MAIL_SEND_TO="serfling@itdata-gera.de" + +SDF_LOCAL_PFAD="C:/Users/Sebastian Serfling/PycharmProjects/SDF-Tool/" +SDF_REMOTE_PFAD="C:/Users/Sebastian Serfling/PycharmProjects/SDF-Tool/" + +LOG_ENABLE="True" +LOG_FILE_PFAD="./logs" + diff --git a/Test_Datenbank/App.sdf b/App.sdf similarity index 73% rename from Test_Datenbank/App.sdf rename to App.sdf index a1a1f1a..0bd5949 100644 Binary files a/Test_Datenbank/App.sdf and b/App.sdf differ diff --git a/errorhandler.py b/errorhandler.py index e69de29..28fc84b 100644 --- a/errorhandler.py +++ b/errorhandler.py @@ -0,0 +1 @@ +import datetime \ No newline at end of file diff --git a/exporter.py b/exporter.py index e69de29..fd9bada 100644 --- a/exporter.py +++ b/exporter.py @@ -0,0 +1,151 @@ +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}") diff --git a/importer.py b/importer.py index e69de29..047402d 100644 --- a/importer.py +++ b/importer.py @@ -0,0 +1 @@ +## Importer aus MSSQL in SDF \ No newline at end of file diff --git a/mail.py b/mail.py index e69de29..2cf0ff5 100644 --- a/mail.py +++ b/mail.py @@ -0,0 +1,3 @@ +## Import für E-Mail Server und Mail Adressen Daten +import dotenv +import datetime diff --git a/main.py b/main.py index e69de29..3debef9 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,15 @@ +## Main File für die Controller +import exporter +import importer +import errorhandler +import mail +import mssqlconnector +## Import von Connector + +import sys +import os +import datetime as dt +import dotenv + + + diff --git a/mssql-connector.py b/mssql-connector.py deleted file mode 100644 index e69de29..0000000 diff --git a/mssqlconnector.py b/mssqlconnector.py new file mode 100644 index 0000000..8e24eda --- /dev/null +++ b/mssqlconnector.py @@ -0,0 +1,2 @@ +## Connector für MSSQL +import dotenv \ No newline at end of file