Skip to content

Commit e397268

Browse files
committed
✨ Add feature to transfer DDL only (#23)
1 parent e96d762 commit e397268

File tree

3 files changed

+69
-42
lines changed

3 files changed

+69
-42
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,21 @@ Options:
4242
separated table names). Implies --without-
4343
foreign-keys which inhibits the transfer of
4444
foreign keys.
45+
4546
-L, --limit-rows INTEGER Transfer only a limited number of rows from
4647
each table.
48+
4749
-C, --collation [BINARY|NOCASE|RTRIM]
4850
Create datatypes of TEXT affinity using a
4951
specified collation sequence. [default:
5052
BINARY]
53+
5154
-K, --prefix-indices Prefix indices with their corresponding
5255
tables. This ensures that their names remain
5356
unique across the SQLite database.
57+
5458
-X, --without-foreign-keys Do not transfer foreign keys.
59+
-W, --without-data Do not transfer table data, DDL only.
5560
-h, --mysql-host TEXT MySQL host. Defaults to localhost.
5661
-P, --mysql-port INTEGER MySQL port. Defaults to 3306.
5762
-S, --skip-ssl Disable MySQL connection encryption.
@@ -61,11 +66,13 @@ Options:
6166
-V, --vacuum Use the VACUUM command to rebuild the SQLite
6267
database file, repacking it into a minimal
6368
amount of disk space
69+
6470
--use-buffered-cursors Use MySQLCursorBuffered for reading the
6571
MySQL database. This can be useful in
6672
situations where multiple queries, with
6773
small result sets, need to be combined or
6874
computed with each other.
75+
6976
-q, --quiet Quiet. Display only errors.
7077
--version Show the version and exit.
7178
--help Show this message and exit.

mysql_to_sqlite3/cli.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@
7373
@click.option(
7474
"-X", "--without-foreign-keys", is_flag=True, help="Do not transfer foreign keys."
7575
)
76+
@click.option(
77+
"-W",
78+
"--without-data",
79+
is_flag=True,
80+
help="Do not transfer table data, DDL only.",
81+
)
7682
@click.option(
7783
"-h", "--mysql-host", default="localhost", help="MySQL host. Defaults to localhost."
7884
)
@@ -120,6 +126,7 @@ def cli(
120126
collation,
121127
prefix_indices,
122128
without_foreign_keys,
129+
without_data,
123130
mysql_host,
124131
mysql_port,
125132
skip_ssl,
@@ -143,6 +150,7 @@ def cli(
143150
prefix_indices=prefix_indices,
144151
without_foreign_keys=without_foreign_keys
145152
or (mysql_tables is not None and len(mysql_tables) > 0),
153+
without_data=without_data,
146154
mysql_host=mysql_host,
147155
mysql_port=mysql_port,
148156
mysql_ssl_disabled=skip_ssl,

mysql_to_sqlite3/transporter.py

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ def __init__(self, **kwargs):
7070
else (kwargs.get("without_foreign_keys") or False)
7171
)
7272

73+
self._without_data = kwargs.get("without_data") or False
74+
7375
self._mysql_user = str(kwargs.get("mysql_user"))
7476

7577
self._mysql_password = (
@@ -520,58 +522,68 @@ def transfer(self):
520522
self._sqlite_cur.execute("PRAGMA foreign_keys=OFF")
521523

522524
for table_name in tables:
525+
self._logger.info(
526+
"%sTransferring table %s",
527+
"[WITHOUT DATA] " if self._without_data else "",
528+
table_name,
529+
)
530+
523531
# reset the chunk
524532
self._current_chunk_number = 0
525533

526534
# create the table
527535
self._create_table(table_name)
528536

529-
# get the size of the data
530-
if self._limit_rows > 0:
531-
# limit to the requested number of rows
532-
self._mysql_cur_dict.execute(
533-
"""
534-
SELECT COUNT(*) AS `total_records`
535-
FROM (SELECT * FROM `{table_name}` LIMIT {limit}) AS `table`
536-
""".format(
537-
table_name=table_name, limit=self._limit_rows
537+
if not self._without_data:
538+
# get the size of the data
539+
if self._limit_rows > 0:
540+
# limit to the requested number of rows
541+
self._mysql_cur_dict.execute(
542+
"""
543+
SELECT COUNT(*) AS `total_records`
544+
FROM (SELECT * FROM `{table_name}` LIMIT {limit}) AS `table`
545+
""".format(
546+
table_name=table_name, limit=self._limit_rows
547+
)
538548
)
539-
)
540-
else:
541-
# get all rows
542-
self._mysql_cur_dict.execute(
543-
"SELECT COUNT(*) AS `total_records` FROM `{table_name}`".format(
544-
table_name=table_name
549+
else:
550+
# get all rows
551+
self._mysql_cur_dict.execute(
552+
"SELECT COUNT(*) AS `total_records` FROM `{table_name}`".format(
553+
table_name=table_name
554+
)
545555
)
556+
total_records = int(
557+
self._mysql_cur_dict.fetchone()["total_records"]
546558
)
547-
total_records = int(self._mysql_cur_dict.fetchone()["total_records"])
548-
549-
# only continue if there is anything to transfer
550-
if total_records > 0:
551-
# populate it
552-
self._logger.info("Transferring table %s", table_name)
553-
self._mysql_cur.execute(
554-
"SELECT * FROM `{table_name}` {limit}".format(
555-
table_name=table_name,
556-
limit="LIMIT {}".format(self._limit_rows)
557-
if self._limit_rows > 0
558-
else "",
559+
560+
# only continue if there is anything to transfer
561+
if total_records > 0:
562+
# populate it
563+
self._mysql_cur.execute(
564+
"SELECT * FROM `{table_name}` {limit}".format(
565+
table_name=table_name,
566+
limit="LIMIT {}".format(self._limit_rows)
567+
if self._limit_rows > 0
568+
else "",
569+
)
570+
)
571+
columns = [column[0] for column in self._mysql_cur.description]
572+
# build the SQL string
573+
sql = """
574+
INSERT OR IGNORE
575+
INTO "{table}" ({fields})
576+
VALUES ({placeholders})
577+
""".format(
578+
table=table_name,
579+
fields=('"{}", ' * len(columns))
580+
.rstrip(" ,")
581+
.format(*columns),
582+
placeholders=("?, " * len(columns)).rstrip(" ,"),
583+
)
584+
self._transfer_table_data(
585+
table_name=table_name, sql=sql, total_records=total_records
559586
)
560-
)
561-
columns = [column[0] for column in self._mysql_cur.description]
562-
# build the SQL string
563-
sql = """
564-
INSERT OR IGNORE
565-
INTO "{table}" ({fields})
566-
VALUES ({placeholders})
567-
""".format(
568-
table=table_name,
569-
fields=('"{}", ' * len(columns)).rstrip(" ,").format(*columns),
570-
placeholders=("?, " * len(columns)).rstrip(" ,"),
571-
)
572-
self._transfer_table_data(
573-
table_name=table_name, sql=sql, total_records=total_records
574-
)
575587
except Exception: # pylint: disable=W0706
576588
raise
577589
finally:

0 commit comments

Comments
 (0)