Skip to content

Commit 4d4cad8

Browse files
committed
221225
1 parent aa81ea9 commit 4d4cad8

9 files changed

Lines changed: 320 additions & 61 deletions
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+
Copies data from one SQLite database table to another SQLite database table.
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+
Retrieves the column names of a table.
14+
15+
Args:
16+
cursor: Database cursor
17+
table_name: Name of the table
18+
19+
Returns:
20+
List of column names
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+
Copies data from a source table to a target table.
37+
38+
Args:
39+
source_db: Path to the source database
40+
target_db: Path to the target database
41+
source_table: Name of the source table
42+
target_table: Name of the target table
43+
where_clause: Optional WHERE condition for source data (e.g., "id > 100")
44+
column_mapping: Optional dictionary for column mapping {source_column: target_column}
45+
46+
Returns:
47+
Number of copied records
48+
"""
49+
try:
50+
# Connect to source database
51+
source_conn = sqlite3.connect(source_db)
52+
source_cursor = source_conn.cursor()
53+
54+
# Connect to target database
55+
target_conn = sqlite3.connect(target_db)
56+
target_cursor = target_conn.cursor()
57+
58+
# Retrieve column names from source table
59+
source_columns = get_table_columns(source_cursor, source_table)
60+
61+
# Retrieve column names from target table
62+
target_columns = get_table_columns(target_cursor, target_table)
63+
64+
# Determine column mapping
65+
if column_mapping:
66+
# Use user-defined mapping
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+
# Automatic mapping: Only common column names
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("No matching columns found!")
80+
return 0
81+
82+
print(f"Columns to copy: {', '.join(columns_to_copy)}")
83+
84+
# Read data from source table
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("No data to copy found.")
94+
return 0
95+
96+
# Insert data into target table
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} records successfully copied.")
105+
106+
return copied_count
107+
108+
except sqlite3.Error as e:
109+
print(f"Database error: {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+
Copies data using ATTACH DATABASE (alternative method).
128+
This method is more efficient for large datasets.
129+
130+
Args:
131+
source_db: Path to the source database
132+
target_db: Path to the target database
133+
source_table: Name of the source table
134+
target_table: Name of the target table
135+
where_clause: Optional WHERE condition
136+
137+
Returns:
138+
Number of copied records
139+
"""
140+
try:
141+
# Connect to target database
142+
conn = sqlite3.connect(target_db)
143+
cursor = conn.cursor()
144+
145+
# Attach source database
146+
cursor.execute(f"ATTACH DATABASE '{source_db}' AS source_db")
147+
148+
# Determine column names
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+
# Find common columns
156+
common_columns = [col for col in source_columns if col in target_columns]
157+
158+
if not common_columns:
159+
print("No matching columns found!")
160+
return 0
161+
162+
print(f"Columns to copy: {', '.join(common_columns)}")
163+
164+
# Copy data
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+
# Detach source database
180+
cursor.execute("DETACH DATABASE source_db")
181+
182+
print(f"{copied_count} records successfully copied.")
183+
184+
return copied_count
185+
186+
except sqlite3.Error as e:
187+
print(f"Database error: {e}")
188+
raise
189+
190+
finally:
191+
if 'conn' in locals():
192+
conn.close()
193+
194+
195+
def main():
196+
"""
197+
Example main program.
198+
"""
199+
# Paths to the databases
200+
base_path = Path(__file__).parent
201+
source_db = base_path / "nfcdb.db"
202+
target_db = base_path / "falk.db"
203+
204+
print("=" * 60)
205+
print("SQLite Data Copy Tool")
206+
print("=" * 60)
207+
208+
# Example 1: Simple copying of all data
209+
print("\n--- Method 1: Two separate connections ---")
210+
try:
211+
count = copy_table_data(
212+
source_db=str(source_db),
213+
target_db=str(target_db),
214+
source_table="tags",
215+
target_table="tag"
216+
)
217+
print(f"✓ {count} records copied")
218+
except Exception as e:
219+
print(f"✗ Error: {e}")
220+
221+
# Example 2: Copying with WHERE condition
222+
print("\n--- Method 2: Using ATTACH DATABASE (more efficient) ---")
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} records copied")
232+
except Exception as e:
233+
print(f"✗ Error: {e}")
234+
235+
# Example 3: Copying with column mapping
236+
print("\n--- Method 3: With custom column mapping ---")
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} records copied")
251+
except Exception as e:
252+
print(f"✗ Error: {e}")
253+
254+
print("\n" + "=" * 60)
255+
print("Done!")
256+
257+
258+
if __name__ == "__main__":
259+
main()
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)