Skip to content

Commit d887b98

Browse files
authored
✨ handle generated columns (#65)
1 parent a9965e0 commit d887b98

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

sqlite3_to_mysql/sqlite_utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import six
1010
from pytimeparse.timeparse import timeparse
1111
from unidecode import unidecode
12+
from packaging import version
1213

1314
if version_info.major == 3 and 4 <= version_info.minor <= 6:
1415
from backports.datetime_fromisoformat import MonkeyPatch # pylint: disable=E0401
@@ -65,3 +66,13 @@ def convert_date(value):
6566
raise ValueError( # pylint: disable=W0707
6667
"DATE field contains Invalid isoformat string: {}".format(err)
6768
)
69+
70+
71+
def check_sqlite_table_xinfo_support(version_string):
72+
"""Check for SQLite table_xinfo support."""
73+
sqlite_version = version.parse(version_string)
74+
if sqlite_version.major > 3 or (
75+
sqlite_version.major == 3 and sqlite_version.minor >= 26
76+
):
77+
return True
78+
return False

sqlite3_to_mysql/transporter.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
convert_decimal,
3131
convert_timedelta,
3232
unicase_compare,
33+
check_sqlite_table_xinfo_support,
3334
)
3435
from .mysql_utils import (
3536
MYSQL_BLOB_COLUMN_TYPES,
@@ -157,6 +158,11 @@ def __init__(self, **kwargs):
157158

158159
self._sqlite_cur = self._sqlite.cursor()
159160

161+
self._sqlite_version = self._get_sqlite_version()
162+
self._sqlite_table_xinfo_support = check_sqlite_table_xinfo_support(
163+
self._sqlite_version
164+
)
165+
160166
try:
161167
self._mysql = mysql.connector.connect(
162168
user=self._mysql_user,
@@ -225,6 +231,17 @@ def _get_mysql_version(self):
225231
)
226232
raise
227233

234+
def _get_sqlite_version(self):
235+
try:
236+
self._sqlite_cur.execute("SELECT sqlite_version()")
237+
return self._sqlite_cur.fetchone()[0]
238+
except (IndexError, sqlite3.Error) as err:
239+
self._logger.error(
240+
"SQLite failed checking for InnoDB version: %s",
241+
err,
242+
)
243+
raise
244+
228245
def _sqlite_table_has_rowid(self, table):
229246
try:
230247
self._sqlite_cur.execute("""SELECT rowid FROM "{}" LIMIT 1""".format(table))
@@ -323,7 +340,14 @@ def _create_table(self, table_name, transfer_rowid=False):
323340
if transfer_rowid:
324341
sql += " `rowid` BIGINT NOT NULL, "
325342

326-
self._sqlite_cur.execute('PRAGMA table_info("{}")'.format(table_name))
343+
self._sqlite_cur.execute(
344+
'PRAGMA {command}("{table_name}")'.format(
345+
command="table_xinfo"
346+
if self._sqlite_table_xinfo_support
347+
else "table_info",
348+
table_name=table_name,
349+
)
350+
)
327351

328352
rows = self._sqlite_cur.fetchall()
329353
compound_primary_key = (
@@ -335,6 +359,12 @@ def _create_table(self, table_name, transfer_rowid=False):
335359
mysql_safe_name = safe_identifier_length(column["name"])
336360
column_type = self._translate_type_from_sqlite_to_mysql(column["type"])
337361

362+
# The "hidden" value is 0 for visible columns, 1 for "hidden" columns,
363+
# 2 for computed virtual columns and 3 for computed stored columns.
364+
# Read more on hidden columns here https://www.sqlite.org/pragma.html#pragma_table_xinfo
365+
if "hidden" in column and column["hidden"] == 1:
366+
continue
367+
338368
sql += " `{name}` {type} {notnull} {default} {auto_increment}, ".format(
339369
name=mysql_safe_name,
340370
type=column_type,

0 commit comments

Comments
 (0)