Skip to content

Conversation

@techouse
Copy link
Owner

@techouse techouse commented Oct 19, 2025

This pull request refactors how MySQL views are converted to SQLite, simplifying the MySQLtoSQLite._mysql_viewdef_to_sqlite interface and improving schema qualifier stripping. The method is now an instance method (not static), no longer takes schema_name or keep_schema parameters, and always strips schema qualifiers matching the current database. Tests and code using this method are updated accordingly, and additional test coverage ensures robust handling of schema qualifiers, including in fallback paths and nested queries.

Refactoring and simplification:

  • Refactored _mysql_viewdef_to_sqlite from a static method to an instance method, removing the schema_name and keep_schema parameters and using the instance's _mysql_database attribute to determine which schema qualifiers to strip. The method now always strips schema qualifiers matching the current database from both table and column references, including in fallback scenarios.
  • Updated all calls to _mysql_viewdef_to_sqlite in the codebase and tests to match the new signature, removing schema_name and keep_schema arguments. [1] [2] [3] [4] [5]

Testing improvements:

  • Enhanced unit tests to use an instance of MySQLtoSQLite with a configured _mysql_database attribute, ensuring correct schema stripping behavior and robust fallback handling when parsing fails. [1] [2]
  • Added new tests to verify that schema qualifiers are stripped from both table and fully-qualified column references, including within nested subqueries and when the SQL parser fails.

Test maintenance:

  • Removed obsolete assertions and parameters from test mocks and assertions to align with the new method signature and behavior. [1] [2]
  • Added missing import for patch in test file.

@techouse techouse self-assigned this Oct 19, 2025
@techouse techouse added the bug Something isn't working label Oct 19, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 19, 2025

Walkthrough

Refactors _mysql_viewdef_to_sqlite from a staticmethod to an instance method, removes schema_name/keep_schema parameters, updates call sites and tests, adds regex fallback stripping on parse failures, and strips database qualifiers from parsed AST nodes before emitting CREATE VIEW SQL.

Changes

Cohort / File(s) Change Summary
Core refactor & view translation
src/mysql_to_sqlite3/transporter.py
Converted _mysql_viewdef_to_sqlite to an instance method (removed @staticmethod, schema_name, keep_schema params); updated _build_create_view_sql call site; added regex-based qualifier stripping for parse failures; added AST traversal to remove database qualifiers from Table and fully-qualified Column nodes; uses self._quote_sqlite_identifier when emitting CREATE VIEW.
Test adjustments — simple stubs
tests/unit/test_views_build_paths_extra.py, tests/unit/test_views_create_view.py
Simplified fake converter/stub signatures to accept only view_select_sql and view_name; removed captured schema_name/keep_schema assertions; preserved existing test flow.
Test refactor & coverage
tests/unit/test_views_sqlglot.py
Refactored tests to instantiate MySQLtoSQLite (patched __init__) and call instance method; removed schema_name argument from calls; added/updated tests covering parse success and fallback behaviours, and stripping of schema qualifiers in various query shapes (nested subqueries, qualified columns).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller as _build_create_view_sql
  participant T as MySQLtoSQLite._mysql_viewdef_to_sqlite
  participant Parser as sqlglot.parse_one

  Caller->>T: call(view_select_sql, view_name)
  T->>Parser: parse_one(view_select_sql)
  alt parse success
    Parser-->>T: AST
    T->>T: traverse AST\nstrip DB qualifiers from Tables/Columns
    T-->>Caller: "CREATE VIEW quoted(view_name) AS <modified SQL>"
  else parse failure (ParseError)
    Parser-->>T: ParseError
    T->>T: regex-strip qualifiers matching self._mysql_database
    T-->>Caller: "CREATE VIEW quoted(view_name) AS <stripped SQL>"
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

🐰 I hopped from static to instance today,

I stripped schema bits that got in the way.
With regex and AST I tidy each view,
Quoted names neat — a cleaner debut.
Hop on, small refactor — hooray!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ⚠️ Warning The pull request description provides detailed and substantive information about the refactoring changes, including a clear summary of modifications to _mysql_viewdef_to_sqlite, updates to test files, and improvements to schema qualifier stripping logic. However, the description is missing significant structural elements required by the repository's template. Specifically, the "Type of change" section with checkbox options (Bug fix, New feature, Breaking change, Documentation update), the "How Has This Been Tested?" section with test checklist, and the "Checklist" section with verification items are entirely absent. While testing improvements are mentioned in the narrative, they are not presented in the requested format, and the formal checklist for code quality verification is not included.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title ":bug: remove TABLE_SCHEMA from SQLite views" is fully related to the main change in the changeset. The title clearly and concisely summarises the primary objective: removing schema qualifiers (TABLE_SCHEMA) from SQLite views. This aligns directly with the core refactoring described in the pull request, which involves simplifying the _mysql_viewdef_to_sqlite method to strip database qualifiers consistently from both tables and fully-qualified columns. The title is specific enough for teammates to understand the focus of the change when scanning the project history.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/views

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Oct 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.50%. Comparing base (05ad606) to head (eae2310).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #112      +/-   ##
==========================================
+ Coverage   93.44%   93.50%   +0.05%     
==========================================
  Files           8        8              
  Lines         900      908       +8     
==========================================
+ Hits          841      849       +8     
  Misses         59       59              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/mysql_to_sqlite3/transporter.py (1)

912-927: Quote view identifiers via helper to handle embedded quotes safely.

Using f'"{view_name}"' can break for names containing double quotes. Reuse _quote_sqlite_identifier for correctness and consistency.

Apply:

-            return f'CREATE VIEW IF NOT EXISTS "{view_name}" AS\n{stripped_sql};'
+            view_ident = self._quote_sqlite_identifier(view_name)
+            return f"CREATE VIEW IF NOT EXISTS {view_ident} AS\n{stripped_sql};"
@@
-        sqlite_select = tree.sql(dialect="sqlite")
-        return f'CREATE VIEW IF NOT EXISTS "{view_name}" AS\n{sqlite_select};'
+        sqlite_select = tree.sql(dialect="sqlite")
+        view_ident = self._quote_sqlite_identifier(view_name)
+        return f"CREATE VIEW IF NOT EXISTS {view_ident} AS\n{sqlite_select};"
tests/unit/test_views_sqlglot.py (1)

1-80: Remove duplicated tests and outdated API calls (will fail CI).

This file duplicates imports and TestViewsSqlglot; the first block still uses the old signature (schema_name/keep_schema), causing TypeErrors and F811 redefinition errors.

Apply this minimal clean-up: keep the lower, updated block and drop the upper one.

- import re
- from unittest.mock import patch
-
- import pytest
-
- from mysql_to_sqlite3.transporter import MySQLtoSQLite
-
-
- class TestViewsSqlglot:
-     def test_mysql_viewdef_to_sqlite_strips_schema_and_transpiles(self) -> None:
-         mysql_select = "SELECT `u`.`id`, `u`.`name` FROM `db`.`users` AS `u` WHERE `u`.`id` > 1"
-         # Use an instance to ensure access to _mysql_database for stripping
-         with patch.object(MySQLtoSQLite, "__init__", return_value=None):
-             inst = MySQLtoSQLite()  # type: ignore[call-arg]
-         inst._mysql_database = "db"  # type: ignore[attr-defined]
-         sql = inst._mysql_viewdef_to_sqlite(
-             view_select_sql=mysql_select,
-             view_name="v_users",
-         )
-         assert sql.startswith('CREATE VIEW IF NOT EXISTS "v_users" AS')
-         # Ensure schema qualifier was removed
-         assert '"db".' not in sql
-         assert "`db`." not in sql
-         # Ensure it targets sqlite dialect (identifiers quoted with ")
-         assert 'FROM "users"' in sql
-         # Ends with single semicolon
-         assert re.search(r";\s*$", sql) is not None
-
-     def test_mysql_viewdef_to_sqlite_parse_fallback(self, monkeypatch: pytest.MonkeyPatch) -> None:
-         # Force parse_one to raise so we hit the fallback path
-         from sqlglot.errors import ParseError
-
-         def boom(*args, **kwargs):
-             raise ParseError("boom")
-
-         monkeypatch.setattr("mysql_to_sqlite3.transporter.parse_one", boom)
-
-         sql_in = "SELECT 1"
-         out = MySQLtoSQLite._mysql_viewdef_to_sqlite(
-             view_select_sql=sql_in,
-             view_name="v1",
-             schema_name="db",
-         )
-         assert out.startswith('CREATE VIEW IF NOT EXISTS "v1" AS')
-         assert "SELECT 1" in out
-         assert out.strip().endswith(";")
-
-     def test_mysql_viewdef_to_sqlite_parse_fallback_strips_schema(self, monkeypatch: pytest.MonkeyPatch) -> None:
-         # Force parse_one to raise so we exercise the fallback path with schema qualifiers
-         from sqlglot.errors import ParseError
-
-         def boom(*args, **kwargs):
-             raise ParseError("boom")
-
-         monkeypatch.setattr("mysql_to_sqlite3.transporter.parse_one", boom)
-
-         mysql_select = "SELECT `u`.`id` FROM `db`.`users` AS `u` WHERE `u`.`id` > 1"
-         out = MySQLtoSQLite._mysql_viewdef_to_sqlite(
-             view_select_sql=mysql_select,
-             view_name="v_users",
-             schema_name="db",
-         )
-         # Should not contain schema qualifier anymore
-         assert "`db`." not in out and '"db".' not in out and " db." not in out
-         # Should still reference the table name
-         assert "FROM `users`" in out or 'FROM "users"' in out or "FROM users" in out
-         assert out.strip().endswith(";")
-
-     def test_mysql_viewdef_to_sqlite_keep_schema_true_preserves_qualifiers(self) -> None:
-         mysql_select = "SELECT `u`.`id` FROM `db`.`users` AS `u`"
-         sql = MySQLtoSQLite._mysql_viewdef_to_sqlite(
-             view_select_sql=mysql_select,
-             view_name="v_users",
-             schema_name="db",
-             keep_schema=True,
-         )
-         # Should not strip the schema when keep_schema=True
-         assert "`db`." in sql or '"db".' in sql
-         assert sql.strip().endswith(";")
+ # (Remove duplicate legacy tests and imports above; keep the updated block below.)

Also applies to: 82-90

🧹 Nitpick comments (3)
src/mysql_to_sqlite3/transporter.py (1)

915-924: Make schema-name comparison case-insensitive.

MySQL schema casing can vary by platform/settings. Lowercasing avoids missed strips.

Apply:

-            if db and db.name.strip('`"') == self._mysql_database:
+            if db and db.name.strip('`"').lower() == self._mysql_database.lower():
@@
-            if db and db.name.strip('`"') == self._mysql_database:
+            if db and db.name.strip('`"').lower() == self._mysql_database.lower():
tests/unit/test_views_sqlglot.py (2)

114-116: Silence “unused arguments” in test monkeypatch helper.

Use throwaway names to avoid ARG001 warnings.

Apply:

-        def boom(*args, **kwargs):
+        def boom(*_, **__):
             raise ParseError("boom")

135-137: Same here: unused arguments in helper.

Mirror the change for consistency.

Apply:

-        def boom(*args, **kwargs):
+        def boom(*_, **__):
             raise ParseError("boom")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05ad606 and 830889c.

📒 Files selected for processing (4)
  • src/mysql_to_sqlite3/transporter.py (1 hunks)
  • tests/unit/test_views_build_paths_extra.py (1 hunks)
  • tests/unit/test_views_create_view.py (1 hunks)
  • tests/unit/test_views_sqlglot.py (4 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
tests/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use pytest; keep tests under tests/ mirroring src/mysql_to_sqlite3/ structure

Files:

  • tests/unit/test_views_build_paths_extra.py
  • tests/unit/test_views_create_view.py
  • tests/unit/test_views_sqlglot.py
tests/unit/test_*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

tests/unit/test_*.py: Add unit tests in tests/unit/ for isolated helpers; create targeted files named test_.py
Add at least one unit test covering new flag behavior/validation
Add unit tests for new type mappings in _translate_type_from_mysql_to_sqlite
Add unit tests for new default expression translations

Files:

  • tests/unit/test_views_build_paths_extra.py
  • tests/unit/test_views_create_view.py
  • tests/unit/test_views_sqlglot.py
{src,tests}/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Adhere to lint suite: Black line length 120 and isort profile=black import ordering for all Python files

Files:

  • tests/unit/test_views_build_paths_extra.py
  • tests/unit/test_views_create_view.py
  • tests/unit/test_views_sqlglot.py
  • src/mysql_to_sqlite3/transporter.py
src/mysql_to_sqlite3/transporter.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/mysql_to_sqlite3/transporter.py: Implement and modify core transfer logic (schema introspection, batching, type/default translation, reconnection handling) in transporter.py
Convert AUTO_INCREMENT single primary keys to INTEGER PRIMARY KEY AUTOINCREMENT only when the translated type is integer; log a warning otherwise
Avoid index naming collisions: if an index name equals its table name or --prefix-indices is set, prefix with

_
Centralize default value translation in _translate_default_from_mysql_to_sqlite; extend this function for new MySQL constructs
Handle JSON columns: if SQLite has JSON1, map MySQL JSON to JSON; otherwise map to TEXT unless --json-as-text is set
Skip foreign key generation when a table subset restriction is applied
Use _setup_logger for logging; do not instantiate new loggers ad hoc
For large tables, prefer chunked transfer using fetchmany(self._chunk_size) and executemany inserts
On CR_SERVER_LOST during schema or data transfer, attempt a single reconnect; preserve this behavior
Disable PRAGMA foreign_keys during bulk load and re-enable in finally; ensure early returns still re-enable
Use INSERT OR IGNORE to handle potential duplicate inserts
Thread new CLI parameters through the MySQLtoSQLite constructor
Raise ValueError in constructor for invalid configuration
When --debug is not set, swallow and log errors; when --debug is set, re-raise for stack inspection
Extend _translate_type_from_mysql_to_sqlite when adding type mappings and add corresponding tests
Extend _translate_default_from_mysql_to_sqlite to support new default expressions and add tests
Centralize progress/UI changes around tqdm and honor the --quiet flag

Files:

  • src/mysql_to_sqlite3/transporter.py
src/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Keep mypy passing (Python 3.9 baseline); avoid untyped dynamic attributes in source code

Files:

  • src/mysql_to_sqlite3/transporter.py
src/mysql_to_sqlite3/{cli.py,transporter.py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/mysql_to_sqlite3/{cli.py,transporter.py}: Never log raw passwords
Support --skip-ssl to disable MySQL SSL; default to encrypted where possible and do not silently change defaults

Files:

  • src/mysql_to_sqlite3/transporter.py
🧠 Learnings (4)
📚 Learning: 2025-10-18T21:08:55.973Z
Learnt from: CR
PR: techouse/mysql-to-sqlite3#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-18T21:08:55.973Z
Learning: Applies to tests/unit/test_*.py : Add unit tests for new type mappings in _translate_type_from_mysql_to_sqlite

Applied to files:

  • tests/unit/test_views_sqlglot.py
📚 Learning: 2025-10-18T21:08:55.973Z
Learnt from: CR
PR: techouse/mysql-to-sqlite3#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-18T21:08:55.973Z
Learning: Applies to src/mysql_to_sqlite3/transporter.py : Extend _translate_type_from_mysql_to_sqlite when adding type mappings and add corresponding tests

Applied to files:

  • tests/unit/test_views_sqlglot.py
📚 Learning: 2025-10-18T21:08:55.973Z
Learnt from: CR
PR: techouse/mysql-to-sqlite3#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-18T21:08:55.973Z
Learning: Applies to tests/** : Use pytest; keep tests under tests/ mirroring src/mysql_to_sqlite3/ structure

Applied to files:

  • tests/unit/test_views_sqlglot.py
📚 Learning: 2025-10-18T21:08:55.973Z
Learnt from: CR
PR: techouse/mysql-to-sqlite3#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-18T21:08:55.973Z
Learning: Applies to src/mysql_to_sqlite3/transporter.py : Extend _translate_default_from_mysql_to_sqlite to support new default expressions and add tests

Applied to files:

  • tests/unit/test_views_sqlglot.py
🧬 Code graph analysis (1)
tests/unit/test_views_sqlglot.py (1)
src/mysql_to_sqlite3/transporter.py (2)
  • MySQLtoSQLite (44-1217)
  • _mysql_viewdef_to_sqlite (898-926)
🪛 Flake8 (7.3.0)
tests/unit/test_views_sqlglot.py

[error] 82-82: redefinition of unused 're' from line 1

(F811)


[error] 83-83: redefinition of unused 'patch' from line 2

(F811)


[error] 87-87: redefinition of unused 'MySQLtoSQLite' from line 6

(F811)


[error] 90-90: redefinition of unused 'TestViewsSqlglot' from line 9

(F811)

🪛 Ruff (0.14.0)
tests/unit/test_views_sqlglot.py

52-52: Unused function argument: args

(ARG001)


52-52: Unused function argument: kwargs

(ARG001)


82-82: Redefinition of unused re from line 1

Remove definition: re

(F811)


83-83: Redefinition of unused patch from line 2

Remove definition: patch

(F811)


87-87: Redefinition of unused MySQLtoSQLite from line 6

Remove definition: MySQLtoSQLite

(F811)


90-90: Redefinition of unused TestViewsSqlglot from line 9

(F811)


114-114: Unused function argument: args

(ARG001)


114-114: Unused function argument: kwargs

(ARG001)


135-135: Unused function argument: args

(ARG001)


135-135: Unused function argument: kwargs

(ARG001)

src/mysql_to_sqlite3/transporter.py

905-905: Do not catch blind exception: Exception

(BLE001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Test (python3.12, mariadb:10.6, 0, false, 3.12)
  • GitHub Check: Test (python3.11, mariadb:10.6, 0, false, 3.11)
  • GitHub Check: Test (python3.9, mariadb:10.6, 0, false, 3.9)
  • GitHub Check: Test (python3.9, mariadb:10.11, 0, false, 3.9)
  • GitHub Check: Test (python3.10, mariadb:10.6, 0, false, 3.10)
  • GitHub Check: Test (python3.12, mariadb:10.0, 1, true, 3.12)
  • GitHub Check: Test (python3.13, mariadb:10.0, 1, true, 3.13)
  • GitHub Check: Test (python3.13, mariadb:10.6, 0, false, 3.13)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
tests/unit/test_views_create_view.py (1)

41-47: LGTM: test double matches the new interface.

The fake converter’s signature and staticmethod patch align with the instance method call site; assertions cover the fallback path well.

tests/unit/test_views_build_paths_extra.py (1)

29-35: LGTM: adapter signature updated correctly.

The new fake aligns with the simplified method; assertions verify propagation as intended.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/test_views_sqlglot.py (1)

33-36: Silence ARG001 for unused test stub parameters.

Rename star-args to underscore variants to satisfy Ruff without changing behaviour.

-        def boom(*args, **kwargs):
+        def boom(*_args, **_kwargs):
             raise ParseError("boom")

Also applies to: 54-57

🧹 Nitpick comments (3)
src/mysql_to_sqlite3/transporter.py (2)

903-914: Make fallback schema stripping case-insensitive.

Database names can differ in case; current regexes only match exact case. Use IGNORECASE to robustly strip qualifiers in the fallback path.

-            sn = re.escape(self._mysql_database)
-            for pat in (rf"`{sn}`\.", rf'"{sn}"\.', rf"\b{sn}\."):
-                stripped_sql = re.sub(pat, "", stripped_sql)
+            sn = re.escape(self._mysql_database)
+            for pat in (rf"`{sn}`\.", rf'"{sn}"\.', rf"\b{sn}\."):
+                stripped_sql = re.sub(pat, "", stripped_sql, flags=re.IGNORECASE)

915-925: Normalise case when removing qualifiers in the AST.

Compare schema names case-insensitively to avoid missing matches on platforms where MySQL treats schema names case-insensitively.

-        for tbl in tree.find_all(exp.Table):
-            db = tbl.args.get("db")
-            if db and db.name.strip('`"') == self._mysql_database:
-                tbl.set("db", None)
+        target_db = str(self._mysql_database).lower()
+        for tbl in tree.find_all(exp.Table):
+            db = tbl.args.get("db")
+            if db and getattr(db, "name", None) and db.name.strip('`"').lower() == target_db:
+                tbl.set("db", None)
         # Also remove schema qualifiers on fully-qualified columns (db.table.column)
-        for col in tree.find_all(exp.Column):
-            db = col.args.get("db")
-            if db and db.name.strip('`"') == self._mysql_database:
-                col.set("db", None)
+        for col in tree.find_all(exp.Column):
+            db = col.args.get("db")
+            if db and getattr(db, "name", None) and db.name.strip('`"').lower() == target_db:
+                col.set("db", None)
tests/unit/test_views_sqlglot.py (1)

92-104: Rename test to reflect current behaviour (no keep_schema parameter).

The name suggests keep_schema=True, but the body asserts stripping. Rename for clarity.

-    def test_mysql_viewdef_to_sqlite_keep_schema_true_preserves_qualifiers(self) -> None:
+    def test_mysql_viewdef_to_sqlite_strips_matching_schema_qualifiers(self) -> None:
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 830889c and 1762399.

📒 Files selected for processing (2)
  • src/mysql_to_sqlite3/transporter.py (1 hunks)
  • tests/unit/test_views_sqlglot.py (3 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
tests/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use pytest; keep tests under tests/ mirroring src/mysql_to_sqlite3/ structure

Files:

  • tests/unit/test_views_sqlglot.py
tests/unit/test_*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

tests/unit/test_*.py: Add unit tests in tests/unit/ for isolated helpers; create targeted files named test_.py
Add at least one unit test covering new flag behavior/validation
Add unit tests for new type mappings in _translate_type_from_mysql_to_sqlite
Add unit tests for new default expression translations

Files:

  • tests/unit/test_views_sqlglot.py
{src,tests}/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Adhere to lint suite: Black line length 120 and isort profile=black import ordering for all Python files

Files:

  • tests/unit/test_views_sqlglot.py
  • src/mysql_to_sqlite3/transporter.py
src/mysql_to_sqlite3/transporter.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/mysql_to_sqlite3/transporter.py: Implement and modify core transfer logic (schema introspection, batching, type/default translation, reconnection handling) in transporter.py
Convert AUTO_INCREMENT single primary keys to INTEGER PRIMARY KEY AUTOINCREMENT only when the translated type is integer; log a warning otherwise
Avoid index naming collisions: if an index name equals its table name or --prefix-indices is set, prefix with

_
Centralize default value translation in _translate_default_from_mysql_to_sqlite; extend this function for new MySQL constructs
Handle JSON columns: if SQLite has JSON1, map MySQL JSON to JSON; otherwise map to TEXT unless --json-as-text is set
Skip foreign key generation when a table subset restriction is applied
Use _setup_logger for logging; do not instantiate new loggers ad hoc
For large tables, prefer chunked transfer using fetchmany(self._chunk_size) and executemany inserts
On CR_SERVER_LOST during schema or data transfer, attempt a single reconnect; preserve this behavior
Disable PRAGMA foreign_keys during bulk load and re-enable in finally; ensure early returns still re-enable
Use INSERT OR IGNORE to handle potential duplicate inserts
Thread new CLI parameters through the MySQLtoSQLite constructor
Raise ValueError in constructor for invalid configuration
When --debug is not set, swallow and log errors; when --debug is set, re-raise for stack inspection
Extend _translate_type_from_mysql_to_sqlite when adding type mappings and add corresponding tests
Extend _translate_default_from_mysql_to_sqlite to support new default expressions and add tests
Centralize progress/UI changes around tqdm and honor the --quiet flag

Files:

  • src/mysql_to_sqlite3/transporter.py
src/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Keep mypy passing (Python 3.9 baseline); avoid untyped dynamic attributes in source code

Files:

  • src/mysql_to_sqlite3/transporter.py
src/mysql_to_sqlite3/{cli.py,transporter.py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/mysql_to_sqlite3/{cli.py,transporter.py}: Never log raw passwords
Support --skip-ssl to disable MySQL SSL; default to encrypted where possible and do not silently change defaults

Files:

  • src/mysql_to_sqlite3/transporter.py
🧠 Learnings (3)
📚 Learning: 2025-10-18T21:08:55.973Z
Learnt from: CR
PR: techouse/mysql-to-sqlite3#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-18T21:08:55.973Z
Learning: Applies to src/mysql_to_sqlite3/transporter.py : Extend _translate_type_from_mysql_to_sqlite when adding type mappings and add corresponding tests

Applied to files:

  • tests/unit/test_views_sqlglot.py
📚 Learning: 2025-10-18T21:08:55.973Z
Learnt from: CR
PR: techouse/mysql-to-sqlite3#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-18T21:08:55.973Z
Learning: Applies to src/mysql_to_sqlite3/transporter.py : Extend _translate_default_from_mysql_to_sqlite to support new default expressions and add tests

Applied to files:

  • tests/unit/test_views_sqlglot.py
📚 Learning: 2025-10-18T21:08:55.973Z
Learnt from: CR
PR: techouse/mysql-to-sqlite3#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-18T21:08:55.973Z
Learning: Applies to tests/unit/test_*.py : Add unit tests for new type mappings in _translate_type_from_mysql_to_sqlite

Applied to files:

  • tests/unit/test_views_sqlglot.py
🧬 Code graph analysis (1)
tests/unit/test_views_sqlglot.py (1)
src/mysql_to_sqlite3/transporter.py (2)
  • MySQLtoSQLite (44-1219)
  • _mysql_viewdef_to_sqlite (898-928)
🪛 Ruff (0.14.0)
tests/unit/test_views_sqlglot.py

54-54: Unused function argument: args

(ARG001)


54-54: Unused function argument: kwargs

(ARG001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Test (python3.10, mariadb:10.0, 1, true, 3.10)
  • GitHub Check: Test (python3.11, mariadb:10.0, 1, true, 3.11)
  • GitHub Check: Test (python3.11, mariadb:5.5, 1, true, 3.11)
  • GitHub Check: Test (python3.9, mariadb:10.0, 1, true, 3.9)
  • GitHub Check: Test (python3.10, mariadb:5.5, 1, true, 3.10)
  • GitHub Check: Test (python3.9, mariadb:5.5, 1, true, 3.9)
  • GitHub Check: Test (python3.13, mariadb:5.5, 1, true, 3.13)
  • GitHub Check: Test (python3.12, mariadb:5.5, 1, true, 3.12)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
src/mysql_to_sqlite3/transporter.py (1)

898-902: LGTM on instance conversion and quoting.

Switch to instance method fits the new design, and consistent identifier quoting for the view name looks good.

Also applies to: 927-929

tests/unit/test_views_sqlglot.py (1)

73-91: LGTM: solid coverage for nested qualified columns.

Good end-to-end assertion that nested subqueries lose schema qualifiers while preserving table names.

@techouse techouse merged commit bdbe09d into master Oct 19, 2025
63 checks passed
@techouse techouse deleted the fix/views branch October 19, 2025 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants