py-auto-migrate 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py-auto-migrate-0.0.1/PKG-INFO +71 -0
- py-auto-migrate-0.0.1/README.md +62 -0
- py-auto-migrate-0.0.1/py-auto-migrate/__init__.py +0 -0
- py-auto-migrate-0.0.1/py-auto-migrate/cli.py +47 -0
- py-auto-migrate-0.0.1/py-auto-migrate/core.py +0 -0
- py-auto-migrate-0.0.1/py-auto-migrate/migrator.py +236 -0
- py-auto-migrate-0.0.1/py_auto_migrate.egg-info/PKG-INFO +71 -0
- py-auto-migrate-0.0.1/py_auto_migrate.egg-info/SOURCES.txt +11 -0
- py-auto-migrate-0.0.1/py_auto_migrate.egg-info/dependency_links.txt +1 -0
- py-auto-migrate-0.0.1/py_auto_migrate.egg-info/requires.txt +5 -0
- py-auto-migrate-0.0.1/py_auto_migrate.egg-info/top_level.txt +1 -0
- py-auto-migrate-0.0.1/setup.cfg +4 -0
- py-auto-migrate-0.0.1/setup.py +35 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: py-auto-migrate
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A Tool For Transferring Data, Tables, And Datasets Between Different Databases.
|
|
5
|
+
Author: Kasra Khaksar
|
|
6
|
+
Author-email: kasrakhaksar17@gmail.com
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
<h1 align="center">
|
|
11
|
+
<strong>Py-Auto-Migrate</strong>
|
|
12
|
+
</h1>
|
|
13
|
+
<p align="center">
|
|
14
|
+
A powerful database migration tool to transfer data (e.g., between MongoDB and MySQL or MongoDB and MongoDB), with automatic table/database creation, existence checks, and support for full database migrations.
|
|
15
|
+
<br><br>
|
|
16
|
+
<a href="https://github.com/kasrakhaksar/py-auto-migrate" target="_blank">
|
|
17
|
+
<img src="https://img.shields.io/badge/GitHub-Repo-blue?logo=github" alt="GitHub" />
|
|
18
|
+
</a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install py-auto-migrate
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
<b>Command Line Interface (CLI)</b>
|
|
36
|
+
```bash
|
|
37
|
+
py-auto-migrate migrate --source <source_uri> --target <target_uri> --table <table_name>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
<p>
|
|
41
|
+
|
|
42
|
+
<b>--source :</b>Source database URI (e.g., mysql://user:pass@host:3306/dbname)
|
|
43
|
+
|
|
44
|
+
<b>--target :</b>Target database URI (e.g., mongodb://localhost:27017/mydb)
|
|
45
|
+
|
|
46
|
+
<b>--table (optional):</b>Specific table/collection to migrate. If omitted, all tables/collections will be
|
|
47
|
+
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Example
|
|
55
|
+
```bash
|
|
56
|
+
py-auto-migrate migrate --source "mongodb://localhost:27017/mydb" --target "mongodb://localhost:27017/mydb2"
|
|
57
|
+
py-auto-migrate migrate --source "mongodb://localhost:27017/mydb" --target "mysql://root:1234@localhost:3306/mydb" --table users
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
<p>You can also use MongoDB → MongoDB or MySQL → MySQL</p>
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Future Plans
|
|
67
|
+
<ul>
|
|
68
|
+
|
|
69
|
+
<li>Add support for creating indexes on tables/collections to improve query performance.</li>
|
|
70
|
+
<li>Support for more databases: Add migrations for PostgreSQL, SQLite.</li>
|
|
71
|
+
</ul>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<strong>Py-Auto-Migrate</strong>
|
|
3
|
+
</h1>
|
|
4
|
+
<p align="center">
|
|
5
|
+
A powerful database migration tool to transfer data (e.g., between MongoDB and MySQL or MongoDB and MongoDB), with automatic table/database creation, existence checks, and support for full database migrations.
|
|
6
|
+
<br><br>
|
|
7
|
+
<a href="https://github.com/kasrakhaksar/py-auto-migrate" target="_blank">
|
|
8
|
+
<img src="https://img.shields.io/badge/GitHub-Repo-blue?logo=github" alt="GitHub" />
|
|
9
|
+
</a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install py-auto-migrate
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
<b>Command Line Interface (CLI)</b>
|
|
27
|
+
```bash
|
|
28
|
+
py-auto-migrate migrate --source <source_uri> --target <target_uri> --table <table_name>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
<p>
|
|
32
|
+
|
|
33
|
+
<b>--source :</b>Source database URI (e.g., mysql://user:pass@host:3306/dbname)
|
|
34
|
+
|
|
35
|
+
<b>--target :</b>Target database URI (e.g., mongodb://localhost:27017/mydb)
|
|
36
|
+
|
|
37
|
+
<b>--table (optional):</b>Specific table/collection to migrate. If omitted, all tables/collections will be
|
|
38
|
+
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Example
|
|
46
|
+
```bash
|
|
47
|
+
py-auto-migrate migrate --source "mongodb://localhost:27017/mydb" --target "mongodb://localhost:27017/mydb2"
|
|
48
|
+
py-auto-migrate migrate --source "mongodb://localhost:27017/mydb" --target "mysql://root:1234@localhost:3306/mydb" --table users
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
<p>You can also use MongoDB → MongoDB or MySQL → MySQL</p>
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## Future Plans
|
|
58
|
+
<ul>
|
|
59
|
+
|
|
60
|
+
<li>Add support for creating indexes on tables/collections to improve query performance.</li>
|
|
61
|
+
<li>Support for more databases: Add migrations for PostgreSQL, SQLite.</li>
|
|
62
|
+
</ul>
|
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from migrator import MongoToMySQL, MongoToMongo , MySQLToMongo , MySQLToMySQL
|
|
3
|
+
|
|
4
|
+
@click.group()
|
|
5
|
+
def main():
|
|
6
|
+
"""Py-Auto-Migrate"""
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
@main.command()
|
|
10
|
+
@click.option('--source', required=True)
|
|
11
|
+
@click.option('--target', required=True)
|
|
12
|
+
@click.option('--table', required=False)
|
|
13
|
+
def migrate(source, target, table):
|
|
14
|
+
if source.startswith("mongodb://") and target.startswith("mysql://"):
|
|
15
|
+
m = MongoToMySQL(source, target)
|
|
16
|
+
if table:
|
|
17
|
+
m.migrate_one(table)
|
|
18
|
+
else:
|
|
19
|
+
m.migrate_all()
|
|
20
|
+
|
|
21
|
+
elif source.startswith("mongodb://") and target.startswith("mongodb://"):
|
|
22
|
+
m = MongoToMongo(source, target)
|
|
23
|
+
if table:
|
|
24
|
+
m.migrate_one(table)
|
|
25
|
+
else:
|
|
26
|
+
m.migrate_all()
|
|
27
|
+
|
|
28
|
+
elif source.startswith("mysql://") and target.startswith("mysql://"):
|
|
29
|
+
m = MySQLToMySQL(source, target)
|
|
30
|
+
if table:
|
|
31
|
+
m.migrate_one(table)
|
|
32
|
+
else:
|
|
33
|
+
m.migrate_all()
|
|
34
|
+
|
|
35
|
+
elif source.startswith("mysql://") and target.startswith("mongodb://"):
|
|
36
|
+
m = MySQLToMongo(source, target)
|
|
37
|
+
if table:
|
|
38
|
+
m.migrate_one(table)
|
|
39
|
+
else:
|
|
40
|
+
m.migrate_all()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
else:
|
|
44
|
+
click.echo("❌ Migration type not supported.")
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
from pymongo import MongoClient
|
|
2
|
+
from mysqlSaver import Saver, CheckerAndReceiver, Connection, Creator
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# ========== Mongo → MySQL ==========
|
|
7
|
+
class MongoToMySQL:
|
|
8
|
+
def __init__(self, mongo_uri, mysql_uri):
|
|
9
|
+
self.mongo_uri = mongo_uri
|
|
10
|
+
self.mysql_uri = mysql_uri
|
|
11
|
+
|
|
12
|
+
def migrate_one(self, table_name):
|
|
13
|
+
db = self._get_mongo_db(self.mongo_uri)
|
|
14
|
+
data = list(db[table_name].find())
|
|
15
|
+
if not data:
|
|
16
|
+
print(f"❌ Collection '{table_name}' in MongoDB is empty.")
|
|
17
|
+
return
|
|
18
|
+
|
|
19
|
+
df = pd.DataFrame(data)
|
|
20
|
+
if "_id" in df.columns:
|
|
21
|
+
df["_id"] = df["_id"].astype(str)
|
|
22
|
+
|
|
23
|
+
host, port, user, password, db_name = self._parse_mysql_uri(self.mysql_uri)
|
|
24
|
+
|
|
25
|
+
# اتصال اولیه بدون دیتابیس برای ساخت دیتابیس
|
|
26
|
+
temp_conn = Connection.connect(host, port, user, password, None)
|
|
27
|
+
creator = Creator(temp_conn)
|
|
28
|
+
creator.database_creator(db_name)
|
|
29
|
+
temp_conn.close()
|
|
30
|
+
|
|
31
|
+
# اتصال به دیتابیس ساخته شده
|
|
32
|
+
conn = Connection.connect(host, port, user, password, db_name)
|
|
33
|
+
|
|
34
|
+
checker = CheckerAndReceiver(conn)
|
|
35
|
+
if checker.table_exist(table_name):
|
|
36
|
+
print(f"⚠ Table '{table_name}' already exists in MySQL. Skipping migration.")
|
|
37
|
+
conn.close()
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
saver = Saver(conn)
|
|
41
|
+
saver.sql_saver(df, table_name)
|
|
42
|
+
conn.close()
|
|
43
|
+
print(f"✅ Migrated {len(df)} rows from MongoDB to MySQL table '{table_name}'")
|
|
44
|
+
|
|
45
|
+
def migrate_all(self):
|
|
46
|
+
db = self._get_mongo_db(self.mongo_uri)
|
|
47
|
+
collections = db.list_collection_names()
|
|
48
|
+
print(f"📦 Found {len(collections)} collections in MongoDB")
|
|
49
|
+
for col in collections:
|
|
50
|
+
print(f"➡ Migrating collection: {col}")
|
|
51
|
+
self.migrate_one(col)
|
|
52
|
+
|
|
53
|
+
def _get_mongo_db(self, mongo_uri):
|
|
54
|
+
client = MongoClient(mongo_uri)
|
|
55
|
+
db_name = mongo_uri.split("/")[-1]
|
|
56
|
+
return client[db_name]
|
|
57
|
+
|
|
58
|
+
def _parse_mysql_uri(self, mysql_uri):
|
|
59
|
+
mysql_uri = mysql_uri.replace("mysql://", "")
|
|
60
|
+
user_pass, host_db = mysql_uri.split("@")
|
|
61
|
+
user, password = user_pass.split(":")
|
|
62
|
+
host_port, db_name = host_db.split("/")
|
|
63
|
+
if ":" in host_port:
|
|
64
|
+
host, port = host_port.split(":")
|
|
65
|
+
port = int(port)
|
|
66
|
+
else:
|
|
67
|
+
host = host_port
|
|
68
|
+
port = 3306
|
|
69
|
+
return host, port, user, password, db_name
|
|
70
|
+
|
|
71
|
+
# ========== Mongo → Mongo ==========
|
|
72
|
+
class MongoToMongo:
|
|
73
|
+
def __init__(self, source_uri, target_uri):
|
|
74
|
+
self.source_uri = source_uri
|
|
75
|
+
self.target_uri = target_uri
|
|
76
|
+
|
|
77
|
+
def migrate_one(self, collection_name):
|
|
78
|
+
source_db = self._get_mongo_db(self.source_uri)
|
|
79
|
+
target_db = self._get_mongo_db(self.target_uri)
|
|
80
|
+
|
|
81
|
+
data = list(source_db[collection_name].find())
|
|
82
|
+
if not data:
|
|
83
|
+
print(f"❌ Collection '{collection_name}' in source MongoDB is empty.")
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
if collection_name in target_db.list_collection_names():
|
|
87
|
+
print(f"⚠ Collection '{collection_name}' already exists in target MongoDB. Skipping.")
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
target_db[collection_name].insert_many(data)
|
|
91
|
+
print(f"✅ Migrated {len(data)} documents from '{collection_name}' to target MongoDB.")
|
|
92
|
+
|
|
93
|
+
def migrate_all(self):
|
|
94
|
+
source_db = self._get_mongo_db(self.source_uri)
|
|
95
|
+
collections = source_db.list_collection_names()
|
|
96
|
+
print(f"📦 Found {len(collections)} collections in source MongoDB")
|
|
97
|
+
for col in collections:
|
|
98
|
+
print(f"➡ Migrating collection: {col}")
|
|
99
|
+
self.migrate_one(col)
|
|
100
|
+
|
|
101
|
+
def _get_mongo_db(self, mongo_uri):
|
|
102
|
+
client = MongoClient(mongo_uri)
|
|
103
|
+
db_name = mongo_uri.split("/")[-1]
|
|
104
|
+
return client[db_name]
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# ========== MySQL → MySQL ==========
|
|
110
|
+
class MySQLToMySQL:
|
|
111
|
+
def __init__(self, source_uri, target_uri):
|
|
112
|
+
self.source_uri = source_uri
|
|
113
|
+
self.target_uri = target_uri
|
|
114
|
+
|
|
115
|
+
def migrate_one(self, table_name):
|
|
116
|
+
# اتصال به دیتابیس مبدأ
|
|
117
|
+
src_host, src_port, src_user, src_pass, src_db = self._parse_mysql_uri(self.source_uri)
|
|
118
|
+
src_conn = Connection.connect(src_host, src_port, src_user, src_pass, src_db)
|
|
119
|
+
src_cursor = src_conn.cursor()
|
|
120
|
+
src_cursor.execute(f"SELECT * FROM {table_name}")
|
|
121
|
+
data = src_cursor.fetchall()
|
|
122
|
+
columns = [desc[0] for desc in src_cursor.description]
|
|
123
|
+
|
|
124
|
+
if not data:
|
|
125
|
+
print(f"❌ Table '{table_name}' in source MySQL is empty.")
|
|
126
|
+
src_conn.close()
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
df = pd.DataFrame(data, columns=columns)
|
|
130
|
+
src_conn.close()
|
|
131
|
+
|
|
132
|
+
# اتصال به دیتابیس مقصد (قبل از ساخت دیتابیس)
|
|
133
|
+
tgt_host, tgt_port, tgt_user, tgt_pass, tgt_db = self._parse_mysql_uri(self.target_uri)
|
|
134
|
+
temp_conn = Connection.connect(tgt_host, tgt_port, tgt_user, tgt_pass, None)
|
|
135
|
+
creator = Creator(temp_conn)
|
|
136
|
+
creator.database_creator(tgt_db)
|
|
137
|
+
temp_conn.close()
|
|
138
|
+
|
|
139
|
+
# اتصال به دیتابیس مقصد
|
|
140
|
+
tgt_conn = Connection.connect(tgt_host, tgt_port, tgt_user, tgt_pass, tgt_db)
|
|
141
|
+
checker = CheckerAndReceiver(tgt_conn)
|
|
142
|
+
if checker.table_exist(table_name):
|
|
143
|
+
print(f"⚠ Table '{table_name}' already exists in target MySQL. Skipping migration.")
|
|
144
|
+
tgt_conn.close()
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
saver = Saver(tgt_conn)
|
|
148
|
+
saver.sql_saver(df, table_name)
|
|
149
|
+
tgt_conn.close()
|
|
150
|
+
print(f"✅ Migrated {len(df)} rows from MySQL table '{table_name}' to target MySQL")
|
|
151
|
+
|
|
152
|
+
def migrate_all(self):
|
|
153
|
+
src_host, src_port, src_user, src_pass, src_db = self._parse_mysql_uri(self.source_uri)
|
|
154
|
+
src_conn = Connection.connect(src_host, src_port, src_user, src_pass, src_db)
|
|
155
|
+
cursor = src_conn.cursor()
|
|
156
|
+
cursor.execute("SHOW TABLES")
|
|
157
|
+
tables = [row[0] for row in cursor.fetchall()]
|
|
158
|
+
src_conn.close()
|
|
159
|
+
|
|
160
|
+
print(f"📦 Found {len(tables)} tables in source MySQL")
|
|
161
|
+
for table in tables:
|
|
162
|
+
print(f"➡ Migrating table: {table}")
|
|
163
|
+
self.migrate_one(table)
|
|
164
|
+
|
|
165
|
+
def _parse_mysql_uri(self, mysql_uri):
|
|
166
|
+
mysql_uri = mysql_uri.replace("mysql://", "")
|
|
167
|
+
user_pass, host_db = mysql_uri.split("@")
|
|
168
|
+
user, password = user_pass.split(":")
|
|
169
|
+
host_port, db_name = host_db.split("/")
|
|
170
|
+
if ":" in host_port:
|
|
171
|
+
host, port = host_port.split(":")
|
|
172
|
+
port = int(port)
|
|
173
|
+
else:
|
|
174
|
+
host = host_port
|
|
175
|
+
port = 3306
|
|
176
|
+
return host, port, user, password, db_name
|
|
177
|
+
|
|
178
|
+
# ========== MySQL → Mongo ==========
|
|
179
|
+
class MySQLToMongo:
|
|
180
|
+
def __init__(self, mysql_uri, mongo_uri):
|
|
181
|
+
self.mysql_uri = mysql_uri
|
|
182
|
+
self.mongo_uri = mongo_uri
|
|
183
|
+
|
|
184
|
+
def migrate_one(self, table_name):
|
|
185
|
+
# اتصال به MySQL
|
|
186
|
+
host, port, user, password, db_name = self._parse_mysql_uri(self.mysql_uri)
|
|
187
|
+
conn = Connection.connect(host, port, user, password, db_name)
|
|
188
|
+
cursor = conn.cursor()
|
|
189
|
+
cursor.execute(f"SELECT * FROM {table_name}")
|
|
190
|
+
data = cursor.fetchall()
|
|
191
|
+
columns = [desc[0] for desc in cursor.description]
|
|
192
|
+
conn.close()
|
|
193
|
+
|
|
194
|
+
if not data:
|
|
195
|
+
print(f"❌ Table '{table_name}' in MySQL is empty.")
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
df = pd.DataFrame(data, columns=columns)
|
|
199
|
+
|
|
200
|
+
# اتصال به Mongo
|
|
201
|
+
client = MongoClient(self.mongo_uri)
|
|
202
|
+
mongo_db_name = self.mongo_uri.split("/")[-1]
|
|
203
|
+
db = client[mongo_db_name]
|
|
204
|
+
|
|
205
|
+
if table_name in db.list_collection_names():
|
|
206
|
+
print(f"⚠ Collection '{table_name}' already exists in target MongoDB. Skipping.")
|
|
207
|
+
return
|
|
208
|
+
|
|
209
|
+
db[table_name].insert_many(df.to_dict('records'))
|
|
210
|
+
print(f"✅ Migrated {len(df)} rows from MySQL table '{table_name}' to MongoDB collection '{table_name}'")
|
|
211
|
+
|
|
212
|
+
def migrate_all(self):
|
|
213
|
+
host, port, user, password, db_name = self._parse_mysql_uri(self.mysql_uri)
|
|
214
|
+
conn = Connection.connect(host, port, user, password, db_name)
|
|
215
|
+
cursor = conn.cursor()
|
|
216
|
+
cursor.execute("SHOW TABLES")
|
|
217
|
+
tables = [row[0] for row in cursor.fetchall()]
|
|
218
|
+
conn.close()
|
|
219
|
+
|
|
220
|
+
print(f"📦 Found {len(tables)} tables in MySQL")
|
|
221
|
+
for table in tables:
|
|
222
|
+
print(f"➡ Migrating table: {table}")
|
|
223
|
+
self.migrate_one(table)
|
|
224
|
+
|
|
225
|
+
def _parse_mysql_uri(self, mysql_uri):
|
|
226
|
+
mysql_uri = mysql_uri.replace("mysql://", "")
|
|
227
|
+
user_pass, host_db = mysql_uri.split("@")
|
|
228
|
+
user, password = user_pass.split(":")
|
|
229
|
+
host_port, db_name = host_db.split("/")
|
|
230
|
+
if ":" in host_port:
|
|
231
|
+
host, port = host_port.split(":")
|
|
232
|
+
port = int(port)
|
|
233
|
+
else:
|
|
234
|
+
host = host_port
|
|
235
|
+
port = 3306
|
|
236
|
+
return host, port, user, password, db_name
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: py-auto-migrate
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A Tool For Transferring Data, Tables, And Datasets Between Different Databases.
|
|
5
|
+
Author: Kasra Khaksar
|
|
6
|
+
Author-email: kasrakhaksar17@gmail.com
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
<h1 align="center">
|
|
11
|
+
<strong>Py-Auto-Migrate</strong>
|
|
12
|
+
</h1>
|
|
13
|
+
<p align="center">
|
|
14
|
+
A powerful database migration tool to transfer data (e.g., between MongoDB and MySQL or MongoDB and MongoDB), with automatic table/database creation, existence checks, and support for full database migrations.
|
|
15
|
+
<br><br>
|
|
16
|
+
<a href="https://github.com/kasrakhaksar/py-auto-migrate" target="_blank">
|
|
17
|
+
<img src="https://img.shields.io/badge/GitHub-Repo-blue?logo=github" alt="GitHub" />
|
|
18
|
+
</a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install py-auto-migrate
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
<b>Command Line Interface (CLI)</b>
|
|
36
|
+
```bash
|
|
37
|
+
py-auto-migrate migrate --source <source_uri> --target <target_uri> --table <table_name>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
<p>
|
|
41
|
+
|
|
42
|
+
<b>--source :</b>Source database URI (e.g., mysql://user:pass@host:3306/dbname)
|
|
43
|
+
|
|
44
|
+
<b>--target :</b>Target database URI (e.g., mongodb://localhost:27017/mydb)
|
|
45
|
+
|
|
46
|
+
<b>--table (optional):</b>Specific table/collection to migrate. If omitted, all tables/collections will be
|
|
47
|
+
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Example
|
|
55
|
+
```bash
|
|
56
|
+
py-auto-migrate migrate --source "mongodb://localhost:27017/mydb" --target "mongodb://localhost:27017/mydb2"
|
|
57
|
+
py-auto-migrate migrate --source "mongodb://localhost:27017/mydb" --target "mysql://root:1234@localhost:3306/mydb" --table users
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
<p>You can also use MongoDB → MongoDB or MySQL → MySQL</p>
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Future Plans
|
|
67
|
+
<ul>
|
|
68
|
+
|
|
69
|
+
<li>Add support for creating indexes on tables/collections to improve query performance.</li>
|
|
70
|
+
<li>Support for more databases: Add migrations for PostgreSQL, SQLite.</li>
|
|
71
|
+
</ul>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
py-auto-migrate/__init__.py
|
|
4
|
+
py-auto-migrate/cli.py
|
|
5
|
+
py-auto-migrate/core.py
|
|
6
|
+
py-auto-migrate/migrator.py
|
|
7
|
+
py_auto_migrate.egg-info/PKG-INFO
|
|
8
|
+
py_auto_migrate.egg-info/SOURCES.txt
|
|
9
|
+
py_auto_migrate.egg-info/dependency_links.txt
|
|
10
|
+
py_auto_migrate.egg-info/requires.txt
|
|
11
|
+
py_auto_migrate.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
py-auto-migrate
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
this_directory = Path(__file__).parent
|
|
4
|
+
long_description = (this_directory / "README.md").read_text()
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
packages = \
|
|
8
|
+
['py-auto-migrate']
|
|
9
|
+
|
|
10
|
+
package_data = \
|
|
11
|
+
{'': ['*']}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
setup_kwargs = {
|
|
15
|
+
'name' :'py-auto-migrate',
|
|
16
|
+
'version':'0.0.1',
|
|
17
|
+
'author':'Kasra Khaksar',
|
|
18
|
+
'author_email':'kasrakhaksar17@gmail.com',
|
|
19
|
+
'description':'A Tool For Transferring Data, Tables, And Datasets Between Different Databases.',
|
|
20
|
+
"long_description" : long_description,
|
|
21
|
+
"long_description_content_type" :'text/markdown',
|
|
22
|
+
'packages': packages,
|
|
23
|
+
'package_data': package_data,
|
|
24
|
+
'python_requires': '>=3.11',
|
|
25
|
+
'install_requires': [
|
|
26
|
+
'pandas',
|
|
27
|
+
'tqdm',
|
|
28
|
+
'pymysql',
|
|
29
|
+
'pymongo',
|
|
30
|
+
'mysqlSaver'
|
|
31
|
+
],
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
setup(**setup_kwargs)
|