Skip to content

Commit aa81ea9

Browse files
committed
221225
1 parent 1332f81 commit aa81ea9

1 file changed

Lines changed: 259 additions & 0 deletions

File tree

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
#!/usr/bin/env python
2+
"""
3+
Kopiert Daten aus einer SQLite-Datenbanktabelle in eine andere SQLite-Datenbanktabelle.
4+
"""
5+
6+
import sqlite3
7+
from pathlib import Path
8+
from typing import List, Tuple, Optional
9+
10+
11+
def get_table_columns(cursor: sqlite3.Cursor, table_name: str) -> List[str]:
12+
"""
13+
Ruft die Spaltennamen einer Tabelle ab.
14+
15+
Args:
16+
cursor: Datenbank-Cursor
17+
table_name: Name der Tabelle
18+
19+
Returns:
20+
Liste der Spaltennamen
21+
"""
22+
cursor.execute(f"PRAGMA table_info({table_name})")
23+
columns = [row[1] for row in cursor.fetchall()]
24+
return columns
25+
26+
27+
def copy_table_data(
28+
source_db: str,
29+
target_db: str,
30+
source_table: str,
31+
target_table: str,
32+
where_clause: Optional[str] = None,
33+
column_mapping: Optional[dict] = None
34+
) -> int:
35+
"""
36+
Kopiert Daten von einer Quelltabelle in eine Zieltabelle.
37+
38+
Args:
39+
source_db: Pfad zur Quelldatenbank
40+
target_db: Pfad zur Zieldatenbank
41+
source_table: Name der Quelltabelle
42+
target_table: Name der Zieltabelle
43+
where_clause: Optionale WHERE-Bedingung für Quelldaten (z.B. "id > 100")
44+
column_mapping: Optionales Dictionary für Spaltenzuordnung {quell_spalte: ziel_spalte}
45+
46+
Returns:
47+
Anzahl der kopierten Datensätze
48+
"""
49+
try:
50+
# Verbindung zur Quelldatenbank
51+
source_conn = sqlite3.connect(source_db)
52+
source_cursor = source_conn.cursor()
53+
54+
# Verbindung zur Zieldatenbank
55+
target_conn = sqlite3.connect(target_db)
56+
target_cursor = target_conn.cursor()
57+
58+
# Spaltennamen der Quelltabelle abrufen
59+
source_columns = get_table_columns(source_cursor, source_table)
60+
61+
# Spaltennamen der Zieltabelle abrufen
62+
target_columns = get_table_columns(target_cursor, target_table)
63+
64+
# Spaltenzuordnung bestimmen
65+
if column_mapping:
66+
# Verwende benutzerdefinierte Zuordnung
67+
columns_to_copy = []
68+
target_cols = []
69+
for src_col, tgt_col in column_mapping.items():
70+
if src_col in source_columns and tgt_col in target_columns:
71+
columns_to_copy.append(src_col)
72+
target_cols.append(tgt_col)
73+
else:
74+
# Automatische Zuordnung: Nur gemeinsame Spaltennamen
75+
columns_to_copy = [col for col in source_columns if col in target_columns]
76+
target_cols = columns_to_copy.copy()
77+
78+
if not columns_to_copy:
79+
print("Keine übereinstimmenden Spalten gefunden!")
80+
return 0
81+
82+
print(f"Zu kopierende Spalten: {', '.join(columns_to_copy)}")
83+
84+
# Daten aus Quelltabelle lesen
85+
query = f"SELECT {', '.join(columns_to_copy)} FROM {source_table}"
86+
if where_clause:
87+
query += f" WHERE {where_clause}"
88+
89+
source_cursor.execute(query)
90+
rows = source_cursor.fetchall()
91+
92+
if not rows:
93+
print("Keine Daten zum Kopieren gefunden.")
94+
return 0
95+
96+
# Daten in Zieltabelle einfügen
97+
placeholders = ', '.join(['?' for _ in target_cols])
98+
insert_query = f"INSERT INTO {target_table} ({', '.join(target_cols)}) VALUES ({placeholders})"
99+
100+
target_cursor.executemany(insert_query, rows)
101+
target_conn.commit()
102+
103+
copied_count = len(rows)
104+
print(f"{copied_count} Datensätze erfolgreich kopiert.")
105+
106+
return copied_count
107+
108+
except sqlite3.Error as e:
109+
print(f"Datenbankfehler: {e}")
110+
raise
111+
112+
finally:
113+
if 'source_conn' in locals():
114+
source_conn.close()
115+
if 'target_conn' in locals():
116+
target_conn.close()
117+
118+
119+
def copy_table_data_with_attach(
120+
source_db: str,
121+
target_db: str,
122+
source_table: str,
123+
target_table: str,
124+
where_clause: Optional[str] = None
125+
) -> int:
126+
"""
127+
Kopiert Daten mittels ATTACH DATABASE (alternative Methode).
128+
Diese Methode ist effizienter für große Datenmengen.
129+
130+
Args:
131+
source_db: Pfad zur Quelldatenbank
132+
target_db: Pfad zur Zieldatenbank
133+
source_table: Name der Quelltabelle
134+
target_table: Name der Zieltabelle
135+
where_clause: Optionale WHERE-Bedingung
136+
137+
Returns:
138+
Anzahl der kopierten Datensätze
139+
"""
140+
try:
141+
# Verbindung zur Zieldatenbank
142+
conn = sqlite3.connect(target_db)
143+
cursor = conn.cursor()
144+
145+
# Quelldatenbank anhängen
146+
cursor.execute(f"ATTACH DATABASE '{source_db}' AS source_db")
147+
148+
# Spaltennamen ermitteln
149+
cursor.execute(f"PRAGMA source_db.table_info({source_table})")
150+
source_columns = [row[1] for row in cursor.fetchall()]
151+
152+
cursor.execute(f"PRAGMA table_info({target_table})")
153+
target_columns = [row[1] for row in cursor.fetchall()]
154+
155+
# Gemeinsame Spalten finden
156+
common_columns = [col for col in source_columns if col in target_columns]
157+
158+
if not common_columns:
159+
print("Keine übereinstimmenden Spalten gefunden!")
160+
return 0
161+
162+
print(f"Zu kopierende Spalten: {', '.join(common_columns)}")
163+
164+
# Daten kopieren
165+
columns_str = ', '.join(common_columns)
166+
query = f"""
167+
INSERT INTO {target_table} ({columns_str})
168+
SELECT {columns_str} FROM source_db.{source_table}
169+
"""
170+
171+
if where_clause:
172+
query += f" WHERE {where_clause}"
173+
174+
cursor.execute(query)
175+
copied_count = cursor.rowcount
176+
177+
conn.commit()
178+
179+
# Quelldatenbank trennen
180+
cursor.execute("DETACH DATABASE source_db")
181+
182+
print(f"{copied_count} Datensätze erfolgreich kopiert.")
183+
184+
return copied_count
185+
186+
except sqlite3.Error as e:
187+
print(f"Datenbankfehler: {e}")
188+
raise
189+
190+
finally:
191+
if 'conn' in locals():
192+
conn.close()
193+
194+
195+
def main():
196+
"""
197+
Beispiel-Hauptprogramm.
198+
"""
199+
# Pfade zu den Datenbanken
200+
base_path = Path(__file__).parent
201+
source_db = base_path / "quelle.db"
202+
target_db = base_path / "ziel.db"
203+
204+
print("=" * 60)
205+
print("SQLite Daten-Kopier-Tool")
206+
print("=" * 60)
207+
208+
# Beispiel 1: Einfaches Kopieren aller Daten
209+
print("\n--- Methode 1: Zwei separate Verbindungen ---")
210+
try:
211+
count = copy_table_data(
212+
source_db=str(source_db),
213+
target_db=str(target_db),
214+
source_table="lieferanten",
215+
target_table="lieferanten"
216+
)
217+
print(f"✓ {count} Datensätze kopiert")
218+
except Exception as e:
219+
print(f"✗ Fehler: {e}")
220+
221+
# Beispiel 2: Kopieren mit WHERE-Bedingung
222+
print("\n--- Methode 2: Mit ATTACH DATABASE (effizienter) ---")
223+
try:
224+
count = copy_table_data_with_attach(
225+
source_db=str(source_db),
226+
target_db=str(target_db),
227+
source_table="lager",
228+
target_table="lager",
229+
where_clause="reserviert = 0"
230+
)
231+
print(f"✓ {count} Datensätze kopiert")
232+
except Exception as e:
233+
print(f"✗ Fehler: {e}")
234+
235+
# Beispiel 3: Kopieren mit Spaltenzuordnung
236+
print("\n--- Methode 3: Mit benutzerdefinierter Spaltenzuordnung ---")
237+
try:
238+
column_mapping = {
239+
"kundennummer": "id",
240+
"name": "kundenname",
241+
"anschrift": "adresse"
242+
}
243+
count = copy_table_data(
244+
source_db=str(source_db),
245+
target_db=str(target_db),
246+
source_table="kunden",
247+
target_table="kunden_kopie",
248+
column_mapping=column_mapping
249+
)
250+
print(f"✓ {count} Datensätze kopiert")
251+
except Exception as e:
252+
print(f"✗ Fehler: {e}")
253+
254+
print("\n" + "=" * 60)
255+
print("Fertig!")
256+
257+
258+
if __name__ == "__main__":
259+
main()

0 commit comments

Comments
 (0)