Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-mysql-to-sqlite3 for
openSUSE:Factory checked in at 2026-10-05 12:56:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-mysql-to-sqlite3 (Old)
and /work/SRC/openSUSE:Factory/.python-mysql-to-sqlite3.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-mysql-to-sqlite3"
Mon Oct 5 12:56:39 2026 rev:6 rq:1382323 version:2.6.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-mysql-to-sqlite3/python-mysql-to-sqlite3.changes
2026-04-26 21:15:23.519414141 +0200
+++
/work/SRC/openSUSE:Factory/.python-mysql-to-sqlite3.new.3698736/python-mysql-to-sqlite3.changes
2026-10-05 12:57:42.086958813 +0200
@@ -1,0 +2,11 @@
+Sun Oct 4 14:32:57 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.6.1:
+ * [FEAT] add MySQL 9.7.0 support
+ * [FIX] improve error message formatting
+ * [DOCS] improve project documentation and user guidance
+ * [CHORE] stop upgrading pip during Docker image builds
+ * [CHORE] update GitHub Actions dependencies
+ * [TEST] improve test readability
+
+-------------------------------------------------------------------
Old:
----
mysql_to_sqlite3-2.6.0.tar.gz
New:
----
mysql_to_sqlite3-2.6.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-mysql-to-sqlite3.spec ++++++
--- /var/tmp/diff_new_pack.Lrnbo6/_old 2026-10-05 12:57:42.730985827 +0200
+++ /var/tmp/diff_new_pack.Lrnbo6/_new 2026-10-05 12:57:42.731985869 +0200
@@ -24,7 +24,7 @@
%{?sle15_python_module_pythons}
Name: python-mysql-to-sqlite3
-Version: 2.6.0
+Version: 2.6.1
Release: 0
Summary: A simple Python tool to transfer data from MySQL to SQLite 3
License: MIT
++++++ mysql_to_sqlite3-2.6.0.tar.gz -> mysql_to_sqlite3-2.6.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mysql_to_sqlite3-2.6.0/.gitignore
new/mysql_to_sqlite3-2.6.1/.gitignore
--- old/mysql_to_sqlite3-2.6.0/.gitignore 2020-02-02 01:00:00.000000000
+0100
+++ new/mysql_to_sqlite3-2.6.1/.gitignore 2020-02-02 01:00:00.000000000
+0100
@@ -124,3 +124,9 @@
# Potential leftovers
tests/db_credentials.json
log.txt
+
+# AI related
+.junie/
+
+# VSCode
+.history
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mysql_to_sqlite3-2.6.0/CHANGELOG.md
new/mysql_to_sqlite3-2.6.1/CHANGELOG.md
--- old/mysql_to_sqlite3-2.6.0/CHANGELOG.md 2020-02-02 01:00:00.000000000
+0100
+++ new/mysql_to_sqlite3-2.6.1/CHANGELOG.md 2020-02-02 01:00:00.000000000
+0100
@@ -1,6 +1,15 @@
+# 2.6.1
+
+* [FEAT] add MySQL 9.7.0 support
+* [FIX] improve error message formatting
+* [DOCS] improve project documentation and user guidance
+* [CHORE] stop upgrading pip during Docker image builds
+* [CHORE] update GitHub Actions dependencies
+* [TEST] improve test readability
+
# 2.6.0
-* [FEAT] Add MySQL SSL certificate options: `--mysql-ssl-ca`,
`--mysql-ssl-cert`, `--mysql-ssl-key`
+* [FEAT] add MySQL SSL certificate options: `--mysql-ssl-ca`,
`--mysql-ssl-cert`, `--mysql-ssl-key`
* [TEST] close DockerClient instances in test fixtures
# 2.5.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mysql_to_sqlite3-2.6.0/PKG-INFO
new/mysql_to_sqlite3-2.6.1/PKG-INFO
--- old/mysql_to_sqlite3-2.6.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/mysql_to_sqlite3-2.6.1/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.4
+Metadata-Version: 2.5
Name: mysql-to-sqlite3
-Version: 2.6.0
+Version: 2.6.1
Summary: A simple Python tool to transfer data from MySQL to SQLite 3
Project-URL: Homepage, https://techouse.github.io/mysql-to-sqlite3/
Project-URL: Documentation, https://techouse.github.io/mysql-to-sqlite3/
@@ -70,11 +70,11 @@
[](https://pypistats.org/packages/mysql-to-sqlite3)
[](https://formulae.brew.sh/formula/mysql-to-sqlite3)
[](https://pypi.org/project/mysql-to-sqlite3/)
-[](https://img.shields.io/static/v1?label=MySQL&message=5.5+|+5.6+|+5.7+|+8.0+|+8.4&color=2b5d80)
-[](https://img.shields.io/static/v1?label=MariaDB&message=5.5+|+10.0+|+10.6+|+10.11+|+11.4+|+11.6+|+11.8&color=C0765A)
+[](https://github.com/techouse/mysql-to-sqlite3/actions/workflows/test.yml)
+[](https://github.com/techouse/mysql-to-sqlite3/actions/workflows/test.yml)
[](https://github.com/techouse/mysql-to-sqlite3/blob/master/LICENSE)
[](CODE-OF-CONDUCT.md)
-[](https://pypi.org/project/sqlite3-to-mysql/)
+[](https://pypi.org/project/mysql-to-sqlite3/)
[](https://github.com/ambv/black)
[](https://www.codacy.com/manual/techouse/mysql-to-sqlite3?utm_source=github.com&utm_medium=referral&utm_content=techouse/mysql-to-sqlite3&utm_campaign=Badge_Grade)
[](https://github.com/techouse/mysql-to-sqlite3/actions/workflows/test.yml)
@@ -86,111 +86,240 @@
# MySQL to SQLite3
-#### A simple Python tool to transfer data from MySQL to SQLite 3.
+A Python CLI for transferring MySQL or MariaDB schema and data to a SQLite 3
database file.
-### How to run
+`mysql2sqlite` reads the source schema from MySQL/MariaDB, creates equivalent
SQLite tables, indexes, views, and
+foreign keys where possible, then transfers table data into the SQLite file.
+
+## Prerequisites
+
+- Python 3.9 or newer, unless you use the Docker image.
+- A reachable MySQL or MariaDB server.
+- A MySQL user that can read the source database and its metadata in
`information_schema`.
+- A writable destination path for the SQLite database file.
+
+See the
+[GitHub Actions CI
matrix](https://github.com/techouse/mysql-to-sqlite3/blob/master/.github/workflows/test.yml)
for
+the current MySQL and MariaDB versions tested by the project. Very old server
versions are more likely to differ in
+type, default-value, authentication, or metadata behavior.
+
+## Installation
+
+Install from PyPI:
```bash
pip install mysql-to-sqlite3
mysql2sqlite --help
```
-### Usage
+On macOS, you can also install with Homebrew:
+
+```bash
+brew install mysql-to-sqlite3
+mysql2sqlite --help
+```
+
+Or run the published Docker image:
+
+```bash
+docker run --rm ghcr.io/techouse/mysql-to-sqlite3:latest --help
+```
+
+## Agent skill
+
+This repo includes an optional agent skill at
+[`skills/mysql-to-sqlite3/`](https://github.com/techouse/mysql-to-sqlite3/tree/master/skills/mysql-to-sqlite3)
for users
+who want Codex or another compatible agent to help prepare a safe
`mysql2sqlite` transfer command. The skill is
+user-facing: it focuses on migration planning, CLI recipes, password-safe
defaults, and MySQL/MariaDB caveats.
+
+## Quick start
+Use `-p` / `--prompt-mysql-password` for interactive password entry. This
avoids putting the password in shell history
+or process listings.
+
+```bash
+mysql2sqlite \
+ --sqlite-file ./app.sqlite3 \
+ --mysql-database app_db \
+ --mysql-user app_user \
+ --prompt-mysql-password \
+ --mysql-host 127.0.0.1 \
+ --mysql-port 3306
```
-Usage: mysql2sqlite [OPTIONS]
-Options:
- -f, --sqlite-file PATH SQLite3 database file [required]
- -d, --mysql-database TEXT MySQL database name [required]
- -u, --mysql-user TEXT MySQL user [required]
- -p, --prompt-mysql-password Prompt for MySQL password
- --mysql-password TEXT MySQL password
- -t, --mysql-tables TUPLE Transfer only these specific tables (space
- separated table names). Implies --without-
- foreign-keys which inhibits the transfer of
- foreign keys. Can not be used together with
- --exclude-mysql-tables.
- -e, --exclude-mysql-tables TUPLE
- Transfer all tables except these specific
- tables (space separated table names).
- Implies --without-foreign-keys which
- inhibits the transfer of foreign keys. Can
- not be used together with --mysql-tables.
- -T, --mysql-views-as-tables Materialize MySQL VIEWs as SQLite tables
- (legacy behavior).
- -L, --limit-rows INTEGER Transfer only a limited number of rows from
- each table.
- -C, --collation [BINARY|NOCASE|RTRIM]
- Create datatypes of TEXT affinity using a
- specified collation sequence. [default:
- BINARY]
- -K, --prefix-indices Prefix indices with their corresponding
- tables. This ensures that their names remain
- unique across the SQLite database.
- -X, --without-foreign-keys Do not transfer foreign keys.
- -Z, --without-tables Do not transfer tables, data only.
- -W, --without-data Do not transfer table data, DDL only.
- -M, --strict Create SQLite STRICT tables when supported.
- -h, --mysql-host TEXT MySQL host. Defaults to localhost.
- -P, --mysql-port INTEGER MySQL port. Defaults to 3306.
- --mysql-charset TEXT MySQL database and table character set
- [default: utf8mb4]
- --mysql-collation TEXT MySQL database and table collation
- --mysql-ssl-ca PATH Path to SSL CA certificate file.
- --mysql-ssl-cert PATH Path to SSL certificate file.
- Must be provided together with
- --mysql-ssl-key.
- --mysql-ssl-key PATH Path to SSL key file.
- Must be provided together with
- --mysql-ssl-cert.
- -S, --skip-ssl Disable MySQL connection encryption.
- Cannot be used with --mysql-ssl-* options.
- -c, --chunk INTEGER Chunk reading/writing SQL records
- -l, --log-file PATH Log file
- --json-as-text Transfer JSON columns as TEXT.
- -V, --vacuum Use the VACUUM command to rebuild the SQLite
- database file, repacking it into a minimal
- amount of disk space
- --use-buffered-cursors Use MySQLCursorBuffered for reading the
- MySQL database. This can be useful in
- situations where multiple queries, with
- small result sets, need to be combined or
- computed with each other.
- -q, --quiet Quiet. Display only errors.
- --debug Debug mode. Will throw exceptions.
- --version Show the version and exit.
- --help Show this message and exit.
+Short options are equivalent:
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p -h 127.0.0.1 -P 3306
```
-#### Docker
+For automation, `--mysql-password` is available, but prefer a secret manager
or environment-expanded value rather than
+typing the password directly into your shell history.
+
+## Common recipes
-If you don't want to install the tool on your system, you can use the Docker
image instead.
+### Run with Docker
+
+Use `host.docker.internal` when the MySQL server is running on the host
machine and the Docker container needs to reach
+it. On Linux Docker Engine, add `--add-host=host.docker.internal:host-gateway`
before the image name if
+`host.docker.internal` is not resolvable.
```bash
docker run -it \
- --workdir $(pwd) \
- --volume $(pwd):$(pwd) \
- --rm ghcr.io/techouse/mysql-to-sqlite3:latest \
- --sqlite-file baz.db \
- --mysql-user foo \
- --mysql-password bar \
- --mysql-database baz \
- --mysql-host host.docker.internal
-```
-
-This will mount your host current working directory (pwd) inside the Docker
container as the current working directory.
-Any files Docker would write to the current working directory are written to
the host directory where you did docker
-run. Note that you have to also use a
-[special
hostname](https://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms)
-`host.docker.internal`
-to access your host machine from inside the Docker container.
+ --rm \
+ --workdir "$PWD" \
+ --volume "$PWD:$PWD" \
+ ghcr.io/techouse/mysql-to-sqlite3:latest \
+ -f ./app.sqlite3 \
+ -d app_db \
+ -u app_user \
+ -p \
+ -h host.docker.internal
+```
-#### Homebrew
+Files written inside the mounted working directory are written back to the
host directory.
-If you're on macOS, you can install the tool using
[Homebrew](https://brew.sh/).
+### Transfer schema only
+
+Create the SQLite tables, indexes, views, and foreign keys without
transferring table rows.
```bash
-brew install mysql-to-sqlite3
-mysql2sqlite --help
+mysql2sqlite -f ./schema.sqlite3 -d app_db -u app_user -p --without-data
+```
+
+### Transfer data into an existing SQLite schema
+
+`--without-tables` skips DDL creation and only inserts data. The SQLite tables
must already exist.
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --without-tables
+```
+
+A common two-step flow is:
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --without-data
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --without-tables
+```
+
+### Transfer only some tables
+
+Table names are space-separated and are consumed until the next CLI option.
+
+```bash
+mysql2sqlite -f ./subset.sqlite3 -d app_db -u app_user -p --mysql-tables users
orders invoices
+```
+
+Transfer everything except selected tables:
+
+```bash
+mysql2sqlite -f ./subset.sqlite3 -d app_db -u app_user -p
--exclude-mysql-tables audit_log temp_imports
+```
+
+Selecting or excluding tables disables foreign key transfer because the
referenced tables may not be present.
+
+### Sample rows from every table
+
+Transfer at most 100 rows from each table:
+
+```bash
+mysql2sqlite -f ./sample.sqlite3 -d app_db -u app_user -p --limit-rows 100
```
+
+### Tune large transfers
+
+The CLI fetches and writes rows in batches by default. Use `--chunk` to tune
the batch size. `--vacuum` repacks the
+SQLite file after the transfer finishes.
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --chunk 50000 --vacuum
+```
+
+### Use SSL certificates
+
+Verify the server certificate with a CA file:
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --mysql-ssl-ca
/path/to/ca.pem
+```
+
+Use a client certificate and key:
+
+```bash
+mysql2sqlite \
+ -f ./app.sqlite3 \
+ -d app_db \
+ -u app_user \
+ -p \
+ --mysql-ssl-ca /path/to/ca.pem \
+ --mysql-ssl-cert /path/to/client-cert.pem \
+ --mysql-ssl-key /path/to/client-key.pem
+```
+
+Use `--skip-ssl` only when you explicitly need to disable MySQL connection
encryption.
+
+## Options at a glance
+
+| Option | Purpose
|
+|---------------------------------------------|----------------------------------------------------------------------------------------------------|
+| `-f`, `--sqlite-file PATH` | Destination SQLite database
file. Required. |
+| `-d`, `--mysql-database TEXT` | Source MySQL/MariaDB database
name. Required. |
+| `-u`, `--mysql-user TEXT` | MySQL/MariaDB user. Required.
|
+| `-p`, `--prompt-mysql-password` | Prompt for the MySQL password.
Preferred for interactive use. |
+| `--mysql-password TEXT` | Provide the MySQL password
directly. Useful for automation, but handle carefully. |
+| `-h`, `--mysql-host TEXT` | MySQL host. Defaults to
`localhost`. |
+| `-P`, `--mysql-port INTEGER` | MySQL port. Defaults to
`3306`. |
+| `-t`, `--mysql-tables TUPLE` | Transfer only the listed
tables. Implies no foreign key transfer. |
+| `-e`, `--exclude-mysql-tables TUPLE` | Transfer every table except
the listed tables. Implies no foreign key transfer. |
+| `-T`, `--mysql-views-as-tables` | Materialize MySQL views as
SQLite tables instead of creating SQLite views. |
+| `-L`, `--limit-rows INTEGER` | Transfer at most this many
rows from each table. `0` means no limit. |
+| `-C`, `--collation [BINARY\|NOCASE\|RTRIM]` | Add a SQLite collation to
text-affinity columns. Defaults to `BINARY`. |
+| `-K`, `--prefix-indices` | Prefix SQLite index names with
their table names. |
+| `-X`, `--without-foreign-keys` | Do not create foreign keys in
the SQLite schema. |
+| `-Z`, `--without-tables` | Skip table/view creation and
transfer data only. |
+| `-W`, `--without-data` | Create schema only and skip
table data. |
+| `-M`, `--strict` | Request SQLite STRICT tables;
older SQLite versions fall back to non-STRICT tables with a warning. |
+| `--mysql-charset TEXT` | MySQL database and table
character set. Defaults to `utf8mb4`. |
+| `--mysql-collation TEXT` | MySQL database and table
collation. Must belong to the selected charset. |
+| `--mysql-ssl-ca PATH` | Path to an SSL CA certificate
file. |
+| `--mysql-ssl-cert PATH` | Path to an SSL client
certificate file. Must be paired with `--mysql-ssl-key`. |
+| `--mysql-ssl-key PATH` | Path to an SSL client key
file. Must be paired with `--mysql-ssl-cert`. |
+| `-S`, `--skip-ssl` | Disable MySQL connection
encryption. Cannot be used with SSL certificate options. |
+| `-c`, `--chunk INTEGER` | Read and write SQL records in
batches. Defaults to `200000`. |
+| `-l`, `--log-file PATH` | Write logs to a file.
|
+| `--json-as-text` | Force MySQL/MariaDB JSON
columns to SQLite `TEXT`. |
+| `-V`, `--vacuum` | Run SQLite `VACUUM` after
transfer. |
+| `--use-buffered-cursors` | Use buffered MySQL cursors.
|
+| `-q`, `--quiet` | Show only errors after the
initial command banner. |
+| `--debug` | Re-raise exceptions for
debugging instead of printing friendly errors. |
+| `--version` | Show environment and
dependency versions. |
+| `--help` | Show CLI help.
|
+
+## Combinations and caveats
+
+- `--mysql-tables` and `--exclude-mysql-tables` are mutually exclusive.
+- `--mysql-tables` or `--exclude-mysql-tables` automatically disables foreign
key transfer.
+- `--without-tables` and `--without-data` cannot be used together because
there would be nothing to do.
+- `--without-tables` requires the destination SQLite schema to already exist.
+- `--skip-ssl` cannot be combined with `--mysql-ssl-ca`, `--mysql-ssl-cert`,
or `--mysql-ssl-key`.
+- `--mysql-ssl-cert` and `--mysql-ssl-key` must be provided together.
+- `--mysql-collation` must be valid for the selected `--mysql-charset`.
+- `--limit-rows` must be `0` or a positive integer. `0` means no limit.
+- `--strict` requests SQLite STRICT tables. On SQLite older than 3.37, the
tool logs a warning and automatically
+ creates non-STRICT tables instead; rerun with SQLite 3.37 or newer to get
STRICT schemas.
+- MySQL views become SQLite views by default. Use `--mysql-views-as-tables`
for the older materialized-table behavior.
+
+## MySQL, MariaDB, and SQLite notes
+
+- MySQL and MariaDB are similar but not identical. Default expressions,
generated defaults, authentication plugins, JSON
+ behavior, and metadata returned from `information_schema` can differ by
server family and version.
+- Older legacy servers may not support newer column types such as native
`JSON`.
+- MySQL/MariaDB `JSON` columns map to SQLite `JSON` only when this tool
detects SQLite JSON1 support. Otherwise they
+ map to `TEXT`. Use `--json-as-text` to force `TEXT`.
+- `ENUM`, `SET`, unsupported spatial/network-style types, and unknown types
fall back to `TEXT`.
+- MySQL `TIMESTAMP` columns are represented as SQLite `DATETIME`.
+- Unsigned integer types are converted to their signed SQLite-compatible type
names.
+- Table names, column names, and index names are quoted for SQLite. Duplicate
SQLite index names are made unique, and
+ `--prefix-indices` can make this behavior explicit.
+- After transfer, verify schema details that are important to your
application, especially defaults, collations, JSON
+ columns, views, and foreign keys.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mysql_to_sqlite3-2.6.0/README.md
new/mysql_to_sqlite3-2.6.1/README.md
--- old/mysql_to_sqlite3-2.6.0/README.md 2020-02-02 01:00:00.000000000
+0100
+++ new/mysql_to_sqlite3-2.6.1/README.md 2020-02-02 01:00:00.000000000
+0100
@@ -2,11 +2,11 @@
[](https://pypistats.org/packages/mysql-to-sqlite3)
[](https://formulae.brew.sh/formula/mysql-to-sqlite3)
[](https://pypi.org/project/mysql-to-sqlite3/)
-[](https://img.shields.io/static/v1?label=MySQL&message=5.5+|+5.6+|+5.7+|+8.0+|+8.4&color=2b5d80)
-[](https://img.shields.io/static/v1?label=MariaDB&message=5.5+|+10.0+|+10.6+|+10.11+|+11.4+|+11.6+|+11.8&color=C0765A)
+[](https://github.com/techouse/mysql-to-sqlite3/actions/workflows/test.yml)
+[](https://github.com/techouse/mysql-to-sqlite3/actions/workflows/test.yml)
[](https://github.com/techouse/mysql-to-sqlite3/blob/master/LICENSE)
[](CODE-OF-CONDUCT.md)
-[](https://pypi.org/project/sqlite3-to-mysql/)
+[](https://pypi.org/project/mysql-to-sqlite3/)
[](https://github.com/ambv/black)
[](https://www.codacy.com/manual/techouse/mysql-to-sqlite3?utm_source=github.com&utm_medium=referral&utm_content=techouse/mysql-to-sqlite3&utm_campaign=Badge_Grade)
[](https://github.com/techouse/mysql-to-sqlite3/actions/workflows/test.yml)
@@ -18,111 +18,240 @@
# MySQL to SQLite3
-#### A simple Python tool to transfer data from MySQL to SQLite 3.
+A Python CLI for transferring MySQL or MariaDB schema and data to a SQLite 3
database file.
-### How to run
+`mysql2sqlite` reads the source schema from MySQL/MariaDB, creates equivalent
SQLite tables, indexes, views, and
+foreign keys where possible, then transfers table data into the SQLite file.
+
+## Prerequisites
+
+- Python 3.9 or newer, unless you use the Docker image.
+- A reachable MySQL or MariaDB server.
+- A MySQL user that can read the source database and its metadata in
`information_schema`.
+- A writable destination path for the SQLite database file.
+
+See the
+[GitHub Actions CI
matrix](https://github.com/techouse/mysql-to-sqlite3/blob/master/.github/workflows/test.yml)
for
+the current MySQL and MariaDB versions tested by the project. Very old server
versions are more likely to differ in
+type, default-value, authentication, or metadata behavior.
+
+## Installation
+
+Install from PyPI:
```bash
pip install mysql-to-sqlite3
mysql2sqlite --help
```
-### Usage
+On macOS, you can also install with Homebrew:
+
+```bash
+brew install mysql-to-sqlite3
+mysql2sqlite --help
+```
+
+Or run the published Docker image:
+
+```bash
+docker run --rm ghcr.io/techouse/mysql-to-sqlite3:latest --help
+```
+
+## Agent skill
+
+This repo includes an optional agent skill at
+[`skills/mysql-to-sqlite3/`](https://github.com/techouse/mysql-to-sqlite3/tree/master/skills/mysql-to-sqlite3)
for users
+who want Codex or another compatible agent to help prepare a safe
`mysql2sqlite` transfer command. The skill is
+user-facing: it focuses on migration planning, CLI recipes, password-safe
defaults, and MySQL/MariaDB caveats.
+
+## Quick start
+Use `-p` / `--prompt-mysql-password` for interactive password entry. This
avoids putting the password in shell history
+or process listings.
+
+```bash
+mysql2sqlite \
+ --sqlite-file ./app.sqlite3 \
+ --mysql-database app_db \
+ --mysql-user app_user \
+ --prompt-mysql-password \
+ --mysql-host 127.0.0.1 \
+ --mysql-port 3306
```
-Usage: mysql2sqlite [OPTIONS]
-Options:
- -f, --sqlite-file PATH SQLite3 database file [required]
- -d, --mysql-database TEXT MySQL database name [required]
- -u, --mysql-user TEXT MySQL user [required]
- -p, --prompt-mysql-password Prompt for MySQL password
- --mysql-password TEXT MySQL password
- -t, --mysql-tables TUPLE Transfer only these specific tables (space
- separated table names). Implies --without-
- foreign-keys which inhibits the transfer of
- foreign keys. Can not be used together with
- --exclude-mysql-tables.
- -e, --exclude-mysql-tables TUPLE
- Transfer all tables except these specific
- tables (space separated table names).
- Implies --without-foreign-keys which
- inhibits the transfer of foreign keys. Can
- not be used together with --mysql-tables.
- -T, --mysql-views-as-tables Materialize MySQL VIEWs as SQLite tables
- (legacy behavior).
- -L, --limit-rows INTEGER Transfer only a limited number of rows from
- each table.
- -C, --collation [BINARY|NOCASE|RTRIM]
- Create datatypes of TEXT affinity using a
- specified collation sequence. [default:
- BINARY]
- -K, --prefix-indices Prefix indices with their corresponding
- tables. This ensures that their names remain
- unique across the SQLite database.
- -X, --without-foreign-keys Do not transfer foreign keys.
- -Z, --without-tables Do not transfer tables, data only.
- -W, --without-data Do not transfer table data, DDL only.
- -M, --strict Create SQLite STRICT tables when supported.
- -h, --mysql-host TEXT MySQL host. Defaults to localhost.
- -P, --mysql-port INTEGER MySQL port. Defaults to 3306.
- --mysql-charset TEXT MySQL database and table character set
- [default: utf8mb4]
- --mysql-collation TEXT MySQL database and table collation
- --mysql-ssl-ca PATH Path to SSL CA certificate file.
- --mysql-ssl-cert PATH Path to SSL certificate file.
- Must be provided together with
- --mysql-ssl-key.
- --mysql-ssl-key PATH Path to SSL key file.
- Must be provided together with
- --mysql-ssl-cert.
- -S, --skip-ssl Disable MySQL connection encryption.
- Cannot be used with --mysql-ssl-* options.
- -c, --chunk INTEGER Chunk reading/writing SQL records
- -l, --log-file PATH Log file
- --json-as-text Transfer JSON columns as TEXT.
- -V, --vacuum Use the VACUUM command to rebuild the SQLite
- database file, repacking it into a minimal
- amount of disk space
- --use-buffered-cursors Use MySQLCursorBuffered for reading the
- MySQL database. This can be useful in
- situations where multiple queries, with
- small result sets, need to be combined or
- computed with each other.
- -q, --quiet Quiet. Display only errors.
- --debug Debug mode. Will throw exceptions.
- --version Show the version and exit.
- --help Show this message and exit.
+Short options are equivalent:
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p -h 127.0.0.1 -P 3306
```
-#### Docker
+For automation, `--mysql-password` is available, but prefer a secret manager
or environment-expanded value rather than
+typing the password directly into your shell history.
+
+## Common recipes
-If you don't want to install the tool on your system, you can use the Docker
image instead.
+### Run with Docker
+
+Use `host.docker.internal` when the MySQL server is running on the host
machine and the Docker container needs to reach
+it. On Linux Docker Engine, add `--add-host=host.docker.internal:host-gateway`
before the image name if
+`host.docker.internal` is not resolvable.
```bash
docker run -it \
- --workdir $(pwd) \
- --volume $(pwd):$(pwd) \
- --rm ghcr.io/techouse/mysql-to-sqlite3:latest \
- --sqlite-file baz.db \
- --mysql-user foo \
- --mysql-password bar \
- --mysql-database baz \
- --mysql-host host.docker.internal
-```
-
-This will mount your host current working directory (pwd) inside the Docker
container as the current working directory.
-Any files Docker would write to the current working directory are written to
the host directory where you did docker
-run. Note that you have to also use a
-[special
hostname](https://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms)
-`host.docker.internal`
-to access your host machine from inside the Docker container.
+ --rm \
+ --workdir "$PWD" \
+ --volume "$PWD:$PWD" \
+ ghcr.io/techouse/mysql-to-sqlite3:latest \
+ -f ./app.sqlite3 \
+ -d app_db \
+ -u app_user \
+ -p \
+ -h host.docker.internal
+```
-#### Homebrew
+Files written inside the mounted working directory are written back to the
host directory.
-If you're on macOS, you can install the tool using
[Homebrew](https://brew.sh/).
+### Transfer schema only
+
+Create the SQLite tables, indexes, views, and foreign keys without
transferring table rows.
```bash
-brew install mysql-to-sqlite3
-mysql2sqlite --help
+mysql2sqlite -f ./schema.sqlite3 -d app_db -u app_user -p --without-data
+```
+
+### Transfer data into an existing SQLite schema
+
+`--without-tables` skips DDL creation and only inserts data. The SQLite tables
must already exist.
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --without-tables
+```
+
+A common two-step flow is:
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --without-data
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --without-tables
+```
+
+### Transfer only some tables
+
+Table names are space-separated and are consumed until the next CLI option.
+
+```bash
+mysql2sqlite -f ./subset.sqlite3 -d app_db -u app_user -p --mysql-tables users
orders invoices
+```
+
+Transfer everything except selected tables:
+
+```bash
+mysql2sqlite -f ./subset.sqlite3 -d app_db -u app_user -p
--exclude-mysql-tables audit_log temp_imports
+```
+
+Selecting or excluding tables disables foreign key transfer because the
referenced tables may not be present.
+
+### Sample rows from every table
+
+Transfer at most 100 rows from each table:
+
+```bash
+mysql2sqlite -f ./sample.sqlite3 -d app_db -u app_user -p --limit-rows 100
```
+
+### Tune large transfers
+
+The CLI fetches and writes rows in batches by default. Use `--chunk` to tune
the batch size. `--vacuum` repacks the
+SQLite file after the transfer finishes.
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --chunk 50000 --vacuum
+```
+
+### Use SSL certificates
+
+Verify the server certificate with a CA file:
+
+```bash
+mysql2sqlite -f ./app.sqlite3 -d app_db -u app_user -p --mysql-ssl-ca
/path/to/ca.pem
+```
+
+Use a client certificate and key:
+
+```bash
+mysql2sqlite \
+ -f ./app.sqlite3 \
+ -d app_db \
+ -u app_user \
+ -p \
+ --mysql-ssl-ca /path/to/ca.pem \
+ --mysql-ssl-cert /path/to/client-cert.pem \
+ --mysql-ssl-key /path/to/client-key.pem
+```
+
+Use `--skip-ssl` only when you explicitly need to disable MySQL connection
encryption.
+
+## Options at a glance
+
+| Option | Purpose
|
+|---------------------------------------------|----------------------------------------------------------------------------------------------------|
+| `-f`, `--sqlite-file PATH` | Destination SQLite database
file. Required. |
+| `-d`, `--mysql-database TEXT` | Source MySQL/MariaDB database
name. Required. |
+| `-u`, `--mysql-user TEXT` | MySQL/MariaDB user. Required.
|
+| `-p`, `--prompt-mysql-password` | Prompt for the MySQL password.
Preferred for interactive use. |
+| `--mysql-password TEXT` | Provide the MySQL password
directly. Useful for automation, but handle carefully. |
+| `-h`, `--mysql-host TEXT` | MySQL host. Defaults to
`localhost`. |
+| `-P`, `--mysql-port INTEGER` | MySQL port. Defaults to
`3306`. |
+| `-t`, `--mysql-tables TUPLE` | Transfer only the listed
tables. Implies no foreign key transfer. |
+| `-e`, `--exclude-mysql-tables TUPLE` | Transfer every table except
the listed tables. Implies no foreign key transfer. |
+| `-T`, `--mysql-views-as-tables` | Materialize MySQL views as
SQLite tables instead of creating SQLite views. |
+| `-L`, `--limit-rows INTEGER` | Transfer at most this many
rows from each table. `0` means no limit. |
+| `-C`, `--collation [BINARY\|NOCASE\|RTRIM]` | Add a SQLite collation to
text-affinity columns. Defaults to `BINARY`. |
+| `-K`, `--prefix-indices` | Prefix SQLite index names with
their table names. |
+| `-X`, `--without-foreign-keys` | Do not create foreign keys in
the SQLite schema. |
+| `-Z`, `--without-tables` | Skip table/view creation and
transfer data only. |
+| `-W`, `--without-data` | Create schema only and skip
table data. |
+| `-M`, `--strict` | Request SQLite STRICT tables;
older SQLite versions fall back to non-STRICT tables with a warning. |
+| `--mysql-charset TEXT` | MySQL database and table
character set. Defaults to `utf8mb4`. |
+| `--mysql-collation TEXT` | MySQL database and table
collation. Must belong to the selected charset. |
+| `--mysql-ssl-ca PATH` | Path to an SSL CA certificate
file. |
+| `--mysql-ssl-cert PATH` | Path to an SSL client
certificate file. Must be paired with `--mysql-ssl-key`. |
+| `--mysql-ssl-key PATH` | Path to an SSL client key
file. Must be paired with `--mysql-ssl-cert`. |
+| `-S`, `--skip-ssl` | Disable MySQL connection
encryption. Cannot be used with SSL certificate options. |
+| `-c`, `--chunk INTEGER` | Read and write SQL records in
batches. Defaults to `200000`. |
+| `-l`, `--log-file PATH` | Write logs to a file.
|
+| `--json-as-text` | Force MySQL/MariaDB JSON
columns to SQLite `TEXT`. |
+| `-V`, `--vacuum` | Run SQLite `VACUUM` after
transfer. |
+| `--use-buffered-cursors` | Use buffered MySQL cursors.
|
+| `-q`, `--quiet` | Show only errors after the
initial command banner. |
+| `--debug` | Re-raise exceptions for
debugging instead of printing friendly errors. |
+| `--version` | Show environment and
dependency versions. |
+| `--help` | Show CLI help.
|
+
+## Combinations and caveats
+
+- `--mysql-tables` and `--exclude-mysql-tables` are mutually exclusive.
+- `--mysql-tables` or `--exclude-mysql-tables` automatically disables foreign
key transfer.
+- `--without-tables` and `--without-data` cannot be used together because
there would be nothing to do.
+- `--without-tables` requires the destination SQLite schema to already exist.
+- `--skip-ssl` cannot be combined with `--mysql-ssl-ca`, `--mysql-ssl-cert`,
or `--mysql-ssl-key`.
+- `--mysql-ssl-cert` and `--mysql-ssl-key` must be provided together.
+- `--mysql-collation` must be valid for the selected `--mysql-charset`.
+- `--limit-rows` must be `0` or a positive integer. `0` means no limit.
+- `--strict` requests SQLite STRICT tables. On SQLite older than 3.37, the
tool logs a warning and automatically
+ creates non-STRICT tables instead; rerun with SQLite 3.37 or newer to get
STRICT schemas.
+- MySQL views become SQLite views by default. Use `--mysql-views-as-tables`
for the older materialized-table behavior.
+
+## MySQL, MariaDB, and SQLite notes
+
+- MySQL and MariaDB are similar but not identical. Default expressions,
generated defaults, authentication plugins, JSON
+ behavior, and metadata returned from `information_schema` can differ by
server family and version.
+- Older legacy servers may not support newer column types such as native
`JSON`.
+- MySQL/MariaDB `JSON` columns map to SQLite `JSON` only when this tool
detects SQLite JSON1 support. Otherwise they
+ map to `TEXT`. Use `--json-as-text` to force `TEXT`.
+- `ENUM`, `SET`, unsupported spatial/network-style types, and unknown types
fall back to `TEXT`.
+- MySQL `TIMESTAMP` columns are represented as SQLite `DATETIME`.
+- Unsigned integer types are converted to their signed SQLite-compatible type
names.
+- Table names, column names, and index names are quoted for SQLite. Duplicate
SQLite index names are made unique, and
+ `--prefix-indices` can make this behavior explicit.
+- After transfer, verify schema details that are important to your
application, especially defaults, collations, JSON
+ columns, views, and foreign keys.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mysql_to_sqlite3-2.6.0/src/mysql_to_sqlite3/__init__.py
new/mysql_to_sqlite3-2.6.1/src/mysql_to_sqlite3/__init__.py
--- old/mysql_to_sqlite3-2.6.0/src/mysql_to_sqlite3/__init__.py 2020-02-02
01:00:00.000000000 +0100
+++ new/mysql_to_sqlite3-2.6.1/src/mysql_to_sqlite3/__init__.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,5 +1,5 @@
"""Utility to transfer data from MySQL to SQLite 3."""
-__version__ = "2.6.0"
+__version__ = "2.6.1"
from .transporter import MySQLtoSQLite
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mysql_to_sqlite3-2.6.0/src/mysql_to_sqlite3/cli.py
new/mysql_to_sqlite3-2.6.1/src/mysql_to_sqlite3/cli.py
--- old/mysql_to_sqlite3-2.6.0/src/mysql_to_sqlite3/cli.py 2020-02-02
01:00:00.000000000 +0100
+++ new/mysql_to_sqlite3-2.6.1/src/mysql_to_sqlite3/cli.py 2020-02-02
01:00:00.000000000 +0100
@@ -242,9 +242,7 @@
)
if bool(mysql_ssl_cert) != bool(mysql_ssl_key):
- raise click.UsageError(
- "Illegal usage: --mysql-ssl-cert and --mysql-ssl-key must be
provided together."
- )
+ raise click.UsageError("Illegal usage: --mysql-ssl-cert and
--mysql-ssl-key must be provided together.")
converter = MySQLtoSQLite(
sqlite_file=sqlite_file,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mysql_to_sqlite3-2.6.0/tests/conftest.py
new/mysql_to_sqlite3-2.6.1/tests/conftest.py
--- old/mysql_to_sqlite3-2.6.0/tests/conftest.py 2020-02-02
01:00:00.000000000 +0100
+++ new/mysql_to_sqlite3-2.6.1/tests/conftest.py 2020-02-02
01:00:00.000000000 +0100
@@ -274,7 +274,9 @@
mysql_connection.close()
else:
if not mysql_available and mysql_connection_retries <= 0:
- raise ConnectionAbortedError("Maximum MySQL connection retries
exhausted! Are you sure MySQL is running?")
+ raise ConnectionAbortedError(
+ "Maximum MySQL connection retries exhausted! Are you sure
MySQL is running?"
+ )
yield # type: ignore[misc]
finally:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mysql_to_sqlite3-2.6.0/tests/unit/test_cli_error_paths.py
new/mysql_to_sqlite3-2.6.1/tests/unit/test_cli_error_paths.py
--- old/mysql_to_sqlite3-2.6.0/tests/unit/test_cli_error_paths.py
2020-02-02 01:00:00.000000000 +0100
+++ new/mysql_to_sqlite3-2.6.1/tests/unit/test_cli_error_paths.py
2020-02-02 01:00:00.000000000 +0100
@@ -171,12 +171,18 @@
result = runner.invoke(
mysql2sqlite,
[
- "-f", "out.sqlite3",
- "-d", "db",
- "-u", "user",
- "--mysql-ssl-ca", str(ca_file),
- "--mysql-ssl-cert", str(cert_file),
- "--mysql-ssl-key", str(key_file),
+ "-f",
+ "out.sqlite3",
+ "-d",
+ "db",
+ "-u",
+ "user",
+ "--mysql-ssl-ca",
+ str(ca_file),
+ "--mysql-ssl-cert",
+ str(cert_file),
+ "--mysql-ssl-key",
+ str(key_file),
],
)
assert result.exit_code == 0, result.output
@@ -221,11 +227,15 @@
result = runner.invoke(
mysql2sqlite,
[
- "-f", "out.sqlite3",
- "-d", "db",
- "-u", "user",
+ "-f",
+ "out.sqlite3",
+ "-d",
+ "db",
+ "-u",
+ "user",
"--skip-ssl",
- "--mysql-ssl-ca", str(ca_file),
+ "--mysql-ssl-ca",
+ str(ca_file),
],
)
assert result.exit_code > 0
@@ -243,10 +253,14 @@
result = runner.invoke(
mysql2sqlite,
[
- "-f", "out.sqlite3",
- "-d", "db",
- "-u", "user",
- "--mysql-ssl-cert", str(cert_file),
+ "-f",
+ "out.sqlite3",
+ "-d",
+ "db",
+ "-u",
+ "user",
+ "--mysql-ssl-cert",
+ str(cert_file),
],
)
assert result.exit_code > 0
@@ -264,10 +278,14 @@
result = runner.invoke(
mysql2sqlite,
[
- "-f", "out.sqlite3",
- "-d", "db",
- "-u", "user",
- "--mysql-ssl-key", str(key_file),
+ "-f",
+ "out.sqlite3",
+ "-d",
+ "db",
+ "-u",
+ "user",
+ "--mysql-ssl-key",
+ str(key_file),
],
)
assert result.exit_code > 0