forked from ei-grad/sqlacrossover
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsqlacrossover.py
More file actions
executable file
·80 lines (60 loc) · 2.43 KB
/
sqlacrossover.py
File metadata and controls
executable file
·80 lines (60 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env python
import argparse
import logging
import sqlalchemy as sa
logger = logging.getLogger(__name__)
class Connection():
def __init__(self, url):
self.engine = sa.create_engine(url)
self.conn = self.engine.connect()
self.meta = sa.MetaData()
self.meta.reflect(self.engine)
tables = sa.schema.sort_tables(self.meta.tables.values())
self.tables = [i.name for i in tables]
class Crossover():
def __init__(self, source, target, bulk):
self.source = Connection(source)
self.target = Connection(target)
self.bulk = bulk
# TODO: implement insert_data_copy
self.insert_data = self.insert_data_simple
def copy_data_in_transaction(self):
with self.target.conn.begin():
self.copy_data()
def copy_data(self):
if set(self.source.tables) != set(self.target.tables):
logger.warning("Source and target database table lists are not identical!")
for table in self.source.tables:
if table in self.target.tables:
self.copy_table(table)
def copy_table(self, table):
offset = 0
source_table = self.target.meta.tables[table]
while True:
data = list(self.source.conn.execute(
sa.select([source_table]).offset(offset).limit(self.bulk)
))
if not data:
break
self.insert_data(table, data)
offset += self.bulk
def insert_data_simple(self, table, data):
self.target.conn.execute(self.target.meta.tables[table].insert(), data)
def main():
logging.basicConfig(format="[%(levelname)s] %(message)s")
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('source', help='Source database SQLAlchemy URL')
parser.add_argument('target', help='Target database SQLAlchemy URL')
parser.add_argument('--bulk', metavar="N", default=10000,
help='Iterate by N rows')
parser.add_argument('--no-transaction', dest='use_transaction',
action='store_false',
help="Don't wrap inserts in a single transaction")
args = parser.parse_args()
crossover = Crossover(args.source, args.target, bulk=args.bulk)
if args.use_transaction:
crossover.copy_data_in_transaction()
else:
crossover.copy_data()
if __name__ == '__main__':
main()