Skip to content

Commit 409e7a9

Browse files
committed
✨ add support for JSONB column handling in SQLite
1 parent 64d12d6 commit 409e7a9

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

src/sqlite3_to_mysql/transporter.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
convert_date,
4141
convert_decimal,
4242
convert_timedelta,
43+
sqlite_jsonb_column_expression,
4344
unicase_compare,
4445
)
4546

@@ -304,6 +305,13 @@ def _get_table_info(self, table_name: str) -> t.List[t.Dict[str, t.Any]]:
304305
self._sqlite_cur.execute(f'PRAGMA {pragma}("{quoted_table_name}")')
305306
return [dict(row) for row in self._sqlite_cur.fetchall()]
306307

308+
@staticmethod
309+
def _declared_type_is_jsonb(column_type: t.Optional[str]) -> bool:
310+
"""Return True when a SQLite column is declared as JSONB."""
311+
if not column_type:
312+
return False
313+
return column_type.strip().upper().startswith("JSONB")
314+
307315
def _get_table_primary_key_columns(self, table_name: str) -> t.List[str]:
308316
"""Return visible primary key columns ordered by their PK sequence."""
309317
primary_key_rows: t.List[t.Dict[str, t.Any]] = sorted(
@@ -516,6 +524,8 @@ def _translate_type_from_sqlite_to_mysql_legacy(self, column_type: str) -> str:
516524
return "TINYINT(1)"
517525
if data_type.startswith(("REAL", "DOUBLE", "FLOAT", "DECIMAL", "DEC", "FIXED")):
518526
return full_column_type
527+
if data_type in {"JSONB"} or data_type.startswith("JSONB"):
528+
return "JSON"
519529
if data_type not in MYSQL_COLUMN_TYPES:
520530
return self._mysql_string_type
521531
return full_column_type
@@ -1323,8 +1333,32 @@ def transfer(self) -> None:
13231333
"view" if object_type == "view" else "table",
13241334
table_name,
13251335
)
1336+
table_column_info: t.List[t.Dict[str, t.Any]] = self._get_table_info(table_name)
1337+
visible_columns: t.List[t.Dict[str, t.Any]] = [
1338+
column for column in table_column_info if column.get("hidden", 0) != 1
1339+
]
1340+
jsonb_columns: t.Set[str] = {
1341+
str(column["name"])
1342+
for column in visible_columns
1343+
if column.get("name") and self._declared_type_is_jsonb(column.get("type"))
1344+
}
1345+
1346+
select_parts: t.List[str] = []
13261347
if transfer_rowid:
1327-
select_list: str = 'rowid as "rowid", *'
1348+
select_parts.append('rowid AS "rowid"')
1349+
1350+
for column in visible_columns:
1351+
column_name: t.Optional[str] = column.get("name")
1352+
if not column_name:
1353+
continue
1354+
quoted_column: str = self._sqlite_quote_ident(column_name)
1355+
if column_name in jsonb_columns:
1356+
select_parts.append(sqlite_jsonb_column_expression(quoted_column))
1357+
else:
1358+
select_parts.append(f'"{quoted_column}"')
1359+
1360+
if select_parts:
1361+
select_list = ", ".join(select_parts)
13281362
else:
13291363
select_list = "*"
13301364
self._sqlite_cur.execute(f'SELECT {select_list} FROM "{quoted_table_name}"')

0 commit comments

Comments
 (0)