Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-sqlite3-to-mysql for openSUSE:Factory checked in at 2024-01-23 22:57:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sqlite3-to-mysql (Old) and /work/SRC/openSUSE:Factory/.python-sqlite3-to-mysql.new.16006 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sqlite3-to-mysql" Tue Jan 23 22:57:09 2024 rev:5 rq:1140875 version:2.1.7 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sqlite3-to-mysql/python-sqlite3-to-mysql.changes 2023-11-02 20:21:20.575555328 +0100 +++ /work/SRC/openSUSE:Factory/.python-sqlite3-to-mysql.new.16006/python-sqlite3-to-mysql.changes 2024-01-23 22:57:22.635120110 +0100 @@ -1,0 +2,8 @@ +Sat Jan 20 13:18:29 UTC 2024 - Enno Gotthold <egotth...@suse.com> + +- Update to 2.1.7 +- Update to 2.1.5 + * feat: add support for UNSIGNED numeric data type conversion + * fix: fix invalid column_type error message + +------------------------------------------------------------------- Old: ---- sqlite3-to-mysql-2.1.0.obscpio New: ---- sqlite3-to-mysql-2.1.7.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sqlite3-to-mysql.spec ++++++ --- /var/tmp/diff_new_pack.ujWiG5/_old 2024-01-23 22:57:23.467150531 +0100 +++ /var/tmp/diff_new_pack.ujWiG5/_new 2024-01-23 22:57:23.471150677 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-sqlite3-to-mysql # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,14 +16,15 @@ # +%define short_name sqlite3-to-mysql %define skip_python2 1 Name: python-sqlite3-to-mysql -Version: 2.1.0 +Version: 2.1.7 Release: 0 Summary: A Python tool to transfer data from SQLite 3 to MySQL License: MIT URL: https://github.com/techouse/sqlite3-to-mysql -Source: https://files.pythonhosted.org/packages/source/s/sqlite3-to-mysql/sqlite3-to-mysql-%{version}.tar.gz +Source: %{short_name}-%{version}.tar.gz BuildRequires: %{python_module SQLAlchemy-Utils} BuildRequires: %{python_module SQLAlchemy} BuildRequires: %{python_module docker} @@ -37,13 +38,15 @@ BuildRequires: python-rpm-macros Requires: python-Unidecode >= 1.3.6 Requires: python-click >= 8.1.3 -Requires: python-mysql-connector-python >= 8.0.33 -Requires: python-packaging >= 23.1 -Requires: python-pytimeparse >= 1.1.8 +Requires: python-mysql-connector-python >= 8.2.0 +Requires: python-packaging +Requires: python-pytimeparse2 Requires: python-simplejson >= 3.19.1 Requires: python-tabulate Requires: python-tqdm >= 4.65.0 Requires: python-typing_extensions +Requires(post): update-alternatives +Requires(postun):update-alternatives BuildArch: noarch # SECTION test requirements BuildRequires: %{python_module Sphinx} ++++++ _service ++++++ --- /var/tmp/diff_new_pack.ujWiG5/_old 2024-01-23 22:57:23.503151847 +0100 +++ /var/tmp/diff_new_pack.ujWiG5/_new 2024-01-23 22:57:23.503151847 +0100 @@ -2,8 +2,9 @@ <service mode="manual" name="obs_scm"> <param name="url">https://github.com/techouse/sqlite3-to-mysql.git</param> <param name="scm">git</param> - <param name="revision">v2.1.0</param> - <param name="versionformat">2.1.0</param> + <param name="revision">v2.1.7</param> + <param name="versionformat">@PARENT_TAG@</param> + <param name="versionrewrite-pattern">v(.*)</param> </service> <service mode="manual" name="set_version"/> <service mode="buildtime" name="tar"/> ++++++ sqlite3-to-mysql-2.1.0.obscpio -> sqlite3-to-mysql-2.1.7.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/.github/FUNDING.yml new/sqlite3-to-mysql-2.1.7/.github/FUNDING.yml --- old/sqlite3-to-mysql-2.1.0/.github/FUNDING.yml 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/.github/FUNDING.yml 2024-01-13 22:07:22.000000000 +0100 @@ -1 +1,2 @@ github: techouse +custom: [ "https://paypal.me/ktusar" ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/.github/workflows/codeql-analysis.yml new/sqlite3-to-mysql-2.1.7/.github/workflows/codeql-analysis.yml --- old/sqlite3-to-mysql-2.1.0/.github/workflows/codeql-analysis.yml 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/.github/workflows/codeql-analysis.yml 2024-01-13 22:07:22.000000000 +0100 @@ -19,7 +19,7 @@ language: [ 'python' ] steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/.github/workflows/docker.yml new/sqlite3-to-mysql-2.1.7/.github/workflows/docker.yml --- old/sqlite3-to-mysql-2.1.0/.github/workflows/docker.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/sqlite3-to-mysql-2.1.7/.github/workflows/docker.yml 2024-01-13 22:07:22.000000000 +0100 @@ -0,0 +1,56 @@ +name: Publish Docker image + +on: + workflow_call: +defaults: + run: + shell: bash + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + environment: + name: docker + url: https://hub.docker.com/r/${{ vars.DOCKERHUB_REPOSITORY }} + steps: + - name: Check out the repo + uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ vars.DOCKERHUB_REPOSITORY }} + ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}}.{{patch}} + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/.github/workflows/publish.yml new/sqlite3-to-mysql-2.1.7/.github/workflows/publish.yml --- old/sqlite3-to-mysql-2.1.0/.github/workflows/publish.yml 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/.github/workflows/publish.yml 2024-01-13 22:07:22.000000000 +0100 @@ -17,8 +17,9 @@ url: https://pypi.org/p/sqlite3-to-mysql permissions: id-token: write + contents: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Compare package version with ref/tag id: compare run: | @@ -80,7 +81,7 @@ with: name: ${{ env.VERSION }} tag_name: ${{ github.ref }} - body: ${{ env.CHANGELOG_PATH }} + body_path: ${{ env.CHANGELOG_PATH }} files: | dist/*.whl dist/*.tar.gz @@ -88,4 +89,11 @@ if: ${{ always() }} run: | rm -rf dist - rm -rf $CHANGELOG_PATH \ No newline at end of file + rm -rf $CHANGELOG_PATH + docker: + needs: build-and-publish + permissions: + packages: write + contents: read + uses: ./.github/workflows/docker.yml + secrets: inherit \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/.github/workflows/test.yml new/sqlite3-to-mysql-2.1.7/.github/workflows/test.yml --- old/sqlite3-to-mysql-2.1.0/.github/workflows/test.yml 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/.github/workflows/test.yml 2024-01-13 22:07:22.000000000 +0100 @@ -16,7 +16,7 @@ analyze: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: @@ -57,6 +57,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:5.5" + legacy_db: 1 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.0" legacy_db: 1 @@ -81,6 +87,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.0" + legacy_db: 1 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.1" legacy_db: 1 @@ -105,6 +117,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.1" + legacy_db: 1 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.2" legacy_db: 0 @@ -129,6 +147,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.2" + legacy_db: 0 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.3" legacy_db: 0 @@ -153,6 +177,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.3" + legacy_db: 0 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.4" legacy_db: 0 @@ -177,6 +207,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.4" + legacy_db: 0 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.5" legacy_db: 0 @@ -201,6 +237,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.5" + legacy_db: 0 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.6" legacy_db: 0 @@ -225,6 +267,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.6" + legacy_db: 0 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mariadb:10.11" legacy_db: 0 @@ -249,6 +297,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mariadb:10.11" + legacy_db: 0 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mysql:5.5" legacy_db: 1 @@ -273,6 +327,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mysql:5.5" + legacy_db: 1 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mysql:5.6" legacy_db: 1 @@ -297,6 +357,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mysql:5.6" + legacy_db: 1 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mysql:5.7" legacy_db: 0 @@ -321,6 +387,12 @@ experimental: false py: "3.11" + - toxenv: "python3.12" + db: "mysql:5.7" + legacy_db: 0 + experimental: false + py: "3.12" + - toxenv: "python3.8" db: "mysql:8.0" legacy_db: 0 @@ -344,6 +416,12 @@ legacy_db: 0 experimental: false py: "3.11" + + - toxenv: "python3.12" + db: "mysql:8.0" + legacy_db: 0 + experimental: false + py: "3.12" continue-on-error: ${{ matrix.experimental }} services: mysql: @@ -354,7 +432,7 @@ MYSQL_ALLOW_EMPTY_PASSWORD: yes options: "--name=mysqld" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.py }} uses: actions/setup-python@v4 with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/CHANGELOG.md new/sqlite3-to-mysql-2.1.7/CHANGELOG.md --- old/sqlite3-to-mysql-2.1.0/CHANGELOG.md 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/CHANGELOG.md 2024-01-13 22:07:22.000000000 +0100 @@ -1,3 +1,29 @@ +# 2.1.6 + +* [FEAT] build both linux/amd64 and linux/arm64 Docker images + +# 2.1.5 + +* [FEAT] add support for UNSIGNED numeric data type conversion +* [FIX] fix invalid column_type error message + +# 2.1.4 + +* [CHORE] maintenance release to publish first containerized release + +# 2.1.3 + +* [FIX] add packaging as a dependency + +# 2.1.2 + +* [FIX] throw more comprehensive error messages when translating column types + +# 2.1.1 + +* [CHORE] add support for Python 3.12 +* [CHORE] bump minimum version of MySQL Connector/Python to 8.2.0 + # 2.1.0 * [CHORE] drop support for Python 3.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/CONTRIBUTING.md new/sqlite3-to-mysql-2.1.7/CONTRIBUTING.md --- old/sqlite3-to-mysql-2.1.0/CONTRIBUTING.md 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/CONTRIBUTING.md 2024-01-13 22:07:22.000000000 +0100 @@ -13,7 +13,7 @@ Ensuring backward compatibility is an imperative requirement. -Currently, the tool supports Python versions 3.8, 3.9, 3.10 and 3.11. +Currently, the tool supports Python versions 3.8, 3.9, 3.10, 3.11, and 3.12. ## MySQL version support diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/Dockerfile new/sqlite3-to-mysql-2.1.7/Dockerfile --- old/sqlite3-to-mysql-2.1.0/Dockerfile 1970-01-01 01:00:00.000000000 +0100 +++ new/sqlite3-to-mysql-2.1.7/Dockerfile 2024-01-13 22:07:22.000000000 +0100 @@ -0,0 +1,8 @@ +FROM python:3.12-alpine + +LABEL maintainer="https://github.com/techouse" + +RUN pip install --no-cache-dir --upgrade pip && \ + pip install --no-cache-dir sqlite3-to-mysql + +ENTRYPOINT ["sqlite3mysql"] \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/LICENSE new/sqlite3-to-mysql-2.1.7/LICENSE --- old/sqlite3-to-mysql-2.1.0/LICENSE 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/LICENSE 2024-01-13 22:07:22.000000000 +0100 @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Klemen Tusar +Copyright (c) 2024 Klemen Tusar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/README.md new/sqlite3-to-mysql-2.1.7/README.md --- old/sqlite3-to-mysql-2.1.0/README.md 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/README.md 2024-01-13 22:07:22.000000000 +0100 @@ -1,17 +1,21 @@ [![PyPI](https://img.shields.io/pypi/v/sqlite3-to-mysql)](https://pypi.org/project/sqlite3-to-mysql/) -[![Downloads](https://pepy.tech/badge/sqlite3-to-mysql)](https://pepy.tech/project/sqlite3-to-mysql) +[![PyPI - Downloads](https://img.shields.io/pypi/dm/sqlite3-to-mysql)](https://pypistats.org/packages/sqlite3-to-mysql) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/sqlite3-to-mysql)](https://pypi.org/project/sqlite3-to-mysql/) [![MySQL Support](https://img.shields.io/static/v1?label=MySQL&message=5.5+|+5.6+|+5.7+|+8.0&color=2b5d80)](https://img.shields.io/static/v1?label=MySQL&message=5.6+|+5.7+|+8.0&color=2b5d80) [![MariaDB Support](https://img.shields.io/static/v1?label=MariaDB&message=5.5+|+10.0+|+10.1+|+10.2+|+10.3+|+10.4+|+10.5+|+10.6|+10.11&color=C0765A)](https://img.shields.io/static/v1?label=MariaDB&message=10.0+|+10.1+|+10.2+|+10.3+|+10.4+|+10.5&color=C0765A) [![GitHub license](https://img.shields.io/github/license/techouse/sqlite3-to-mysql)](https://github.com/techouse/sqlite3-to-mysql/blob/master/LICENSE) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE-OF-CONDUCT.md) +[![PyPI - Format](https://img.shields.io/pypi/format/sqlite3-to-mysql)]((https://pypi.org/project/sqlite3-to-mysql/)) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/d33b59d35b924711aae9418741a923ae)](https://www.codacy.com/manual/techouse/sqlite3-to-mysql?utm_source=github.com&utm_medium=referral&utm_content=techouse/sqlite3-to-mysql&utm_campaign=Badge_Grade) -[![Build Status](https://github.com/techouse/sqlite3-to-mysql/workflows/Test/badge.svg)](https://github.com/techouse/sqlite3-to-mysql/actions?query=workflow%3ATest) +[![Test Status](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/test.yml/badge.svg)](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/test.yml) +[![CodeQL Status](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/codeql-analysis.yml) +[![Publish PyPI Package Status](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/publish.yml/badge.svg)](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/publish.yml) +[![Publish Docker Image](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/docker.yml/badge.svg)](https://github.com/techouse/sqlite3-to-mysql/actions/workflows/docker.yml) [![codecov](https://codecov.io/gh/techouse/sqlite3-to-mysql/branch/master/graph/badge.svg)](https://codecov.io/gh/techouse/sqlite3-to-mysql) +[![GitHub Sponsors](https://img.shields.io/github/sponsors/techouse)](https://github.com/sponsors/techouse) [![GitHub stars](https://img.shields.io/github/stars/techouse/sqlite3-to-mysql.svg?style=social&label=Star&maxAge=2592000)](https://github.com/techouse/sqlite3-to-mysql/stargazers) - # SQLite3 to MySQL #### A simple Python tool to transfer data from SQLite 3 to MySQL. @@ -24,6 +28,7 @@ ``` ### Usage + ``` Usage: sqlite3mysql [OPTIONS] @@ -76,3 +81,35 @@ --version Show the version and exit. --help Show this message and exit. ``` + +#### Docker + +If you don't want to install the tool on your system, you can use the Docker image instead. + +```bash +docker run -it \ + --workdir $(pwd) \ + --volume $(pwd):$(pwd) \ + --rm ghcr.io/techouse/sqlite3-to-mysql: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. + +#### Homebrew + +If you're on macOS, you can install the tool using [Homebrew](https://brew.sh/). + +```bash +brew tap techouse/sqlite3-to-mysql +brew install sqlite3-to-mysql +sqlite3mysql --help +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/pyproject.toml new/sqlite3-to-mysql-2.1.7/pyproject.toml --- old/sqlite3-to-mysql-2.1.0/pyproject.toml 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/pyproject.toml 2024-01-13 22:07:22.000000000 +0100 @@ -11,7 +11,6 @@ authors = [ { name = "Klemen Tusar", email = "techo...@gmail.com" }, ] -urls = { Source = "https://github.com/techouse/sqlite3-to-mysql" } keywords = [ "sqlite3", "mysql", @@ -34,22 +33,29 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database", ] dependencies = [ "Click>=8.1.3", - "mysql-connector-python>=8.0.33", + "mysql-connector-python>=8.2.0", "pytimeparse2", "simplejson>=3.19.1", "tqdm>=4.65.0", - "packaging>=23.1", "tabulate", "Unidecode>=1.3.6", "typing_extensions", + "packaging", ] dynamic = ["version"] +[project.urls] +Source = "https://github.com/techouse/sqlite3-to-mysql" +Changelog = "https://github.com/techouse/sqlite3-to-mysql/blob/master/CHANGELOG.md" +Sponsor = "https://github.com/sponsors/techouse" +PayPal = "https://paypal.me/ktusar" + [tool.hatch.version] path = "sqlite3_to_mysql/__init__.py" @@ -69,7 +75,7 @@ [tool.black] line-length = 120 -target-version = ["py38", "py39", "py310", "py311"] +target-version = ["py38", "py39", "py310", "py311", "py312"] include = '\.pyi?$' exclude = ''' ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/requirements_dev.txt new/sqlite3-to-mysql-2.1.7/requirements_dev.txt --- old/sqlite3-to-mysql-2.1.0/requirements_dev.txt 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/requirements_dev.txt 2024-01-13 22:07:22.000000000 +0100 @@ -2,7 +2,7 @@ docker>=6.1.3 factory-boy Faker>=18.10.0 -mysql-connector-python>=8.0.33 +mysql-connector-python>=8.2.0 PyMySQL>=1.0.3 pytest>=7.3.1 pytest-cov @@ -17,7 +17,7 @@ tox tqdm>=4.65.0 types-tqdm -packaging>=23.1 +packaging tabulate types-tabulate Unidecode>=1.3.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/__init__.py new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/__init__.py --- old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/__init__.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/__init__.py 2024-01-13 22:07:22.000000000 +0100 @@ -1,4 +1,4 @@ """Utility to transfer data from SQLite 3 to MySQL.""" -__version__ = "2.1.0" +__version__ = "2.1.7" from .transporter import SQLite3toMySQL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/cli.py new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/cli.py --- old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/cli.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/cli.py 2024-01-13 22:07:22.000000000 +0100 @@ -2,18 +2,28 @@ import os import sys import typing as t +from datetime import datetime import click from mysql.connector import CharacterSet from tabulate import tabulate from . import SQLite3toMySQL +from . import __version__ as package_version from .click_utils import OptionEatAll, prompt_password from .debug_info import info from .mysql_utils import MYSQL_INSERT_METHOD, MYSQL_TEXT_COLUMN_TYPES, mysql_supported_character_sets -@click.command() +_copyright_header: str = f"sqlite3mysql version {package_version} Copyright (c) 2018-{datetime.now().year} Klemen Tusar" + + +@click.command( + name="sqlite3mysql", + help=_copyright_header, + no_args_is_help=True, + epilog="For more information, visit https://github.com/techouse/sqlite3-to-mysql", +) @click.option( "-f", "--sqlite-file", @@ -85,7 +95,7 @@ @click.option( "--mysql-charset", metavar="TEXT", - type=click.Choice(list(CharacterSet.get_supported()), case_sensitive=False), + type=click.Choice(list(CharacterSet().get_supported()), case_sensitive=False), default="utf8mb4", show_default=True, help="MySQL database and table character set", @@ -140,6 +150,7 @@ debug: bool, ) -> None: """Transfer SQLite to MySQL using the provided CLI options.""" + click.echo(_copyright_header) try: if mysql_collation: charset_collations: t.Tuple[str, ...] = tuple( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/debug_info.py new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/debug_info.py --- old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/debug_info.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/debug_info.py 2024-01-13 22:07:22.000000000 +0100 @@ -7,7 +7,7 @@ import sqlite3 import sys import typing as t -from distutils.spawn import find_executable # pylint: disable=W0402 +from shutil import which from subprocess import check_output import click @@ -55,7 +55,7 @@ def _mysql_version() -> str: - if find_executable("mysql"): + if which("mysql") is not None: try: mysql_version: t.Union[str, bytes] = check_output(["mysql", "-V"]) try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/mysql_utils.py new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/mysql_utils.py --- old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/mysql_utils.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/mysql_utils.py 2024-01-13 22:07:22.000000000 +0100 @@ -95,7 +95,7 @@ except KeyError: continue else: - for charset in CharacterSet.get_supported(): + for charset in CharacterSet().get_supported(): for index, info in enumerate(MYSQL_CHARACTER_SETS): if info is not None: try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/transporter.py new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/transporter.py --- old/sqlite3-to-mysql-2.1.0/sqlite3_to_mysql/transporter.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/sqlite3_to_mysql/transporter.py 2024-01-13 22:07:22.000000000 +0100 @@ -48,7 +48,8 @@ """Use this class to transfer an SQLite 3 database to MySQL.""" COLUMN_PATTERN: t.Pattern[str] = re.compile(r"^[^(]+") - COLUMN_LENGTH_PATTERN: t.Pattern[str] = re.compile(r"\(\d+\)$") + COLUMN_LENGTH_PATTERN: t.Pattern[str] = re.compile(r"\(\d+\)") + COLUMN_UNSIGNED_PATTERN: t.Pattern[str] = re.compile(r"\bUNSIGNED\b", re.IGNORECASE) MYSQL_CONNECTOR_VERSION: version.Version = version.parse(mysql_connector_version_string) @@ -103,7 +104,7 @@ self._mysql_charset = kwargs.get("mysql_charset") or "utf8mb4" self._mysql_collation = ( - kwargs.get("mysql_collation") or CharacterSet.get_default_collation(self._mysql_charset.lower())[0] + kwargs.get("mysql_collation") or CharacterSet().get_default_collation(self._mysql_charset.lower())[0] ) if not kwargs.get("mysql_collation") and self._mysql_collation == "utf8mb4_0900_ai_ci": self._mysql_collation = "utf8mb4_general_ci" @@ -249,11 +250,13 @@ def _translate_type_from_sqlite_to_mysql(self, column_type: str) -> str: """This could be optimized even further, however is seems adequate.""" full_column_type: str = column_type.upper() + unsigned: bool = self.COLUMN_UNSIGNED_PATTERN.search(full_column_type) is not None match: t.Optional[t.Match[str]] = self._valid_column_type(column_type) if not match: - raise ValueError("Invalid column_type!") + raise ValueError(f'"{column_type}" is not a valid column_type!') data_type: str = match.group(0).upper() + if data_type in {"TEXT", "CLOB", "STRING"}: return self._mysql_text_type if data_type in {"CHARACTER", "NCHAR", "NATIVE CHARACTER"}: @@ -267,25 +270,36 @@ match = self._valid_column_type(self._mysql_string_type) if match: return match.group(0).upper() + length - if data_type == "DOUBLE PRECISION": - return "DOUBLE" if data_type == "UNSIGNED BIG INT": - return "BIGINT" + self._column_type_length(column_type) + " UNSIGNED" - if data_type in {"INT1", "INT2"}: - return self._mysql_integer_type - if data_type in {"INTEGER", "INT"}: + return f"BIGINT{self._column_type_length(column_type)} UNSIGNED" + if data_type.startswith(("TINYINT", "INT1")): + print("length", self._column_type_length(column_type)) + return f"TINYINT{self._column_type_length(column_type)}{' UNSIGNED' if unsigned else ''}" + if data_type.startswith(("SMALLINT", "INT2")): + return f"SMALLINT{self._column_type_length(column_type)}{' UNSIGNED' if unsigned else ''}" + if data_type.startswith(("MEDIUMINT", "INT3")): + return f"MEDIUMINT{self._column_type_length(column_type)}{' UNSIGNED' if unsigned else ''}" + if data_type.startswith("INT4"): + return f"INT{self._column_type_length(column_type)}{' UNSIGNED' if unsigned else ''}" + if data_type.startswith(("BIGINT", "INT8")): + return f"BIGINT{self._column_type_length(column_type)}{' UNSIGNED' if unsigned else ''}" + if data_type.startswith(("INT64", "NUMERIC")): + return f"BIGINT{self._column_type_length(column_type, 19)}{' UNSIGNED' if unsigned else ''}" + if data_type.startswith(("INTEGER", "INT")): length = self._column_type_length(column_type) if not length: - return self._mysql_integer_type + if "UNSIGNED" in self._mysql_integer_type: + return self._mysql_integer_type + return f"{self._mysql_integer_type}{' UNSIGNED' if unsigned else ''}" match = self._valid_column_type(self._mysql_integer_type) if match: - if self._mysql_integer_type.endswith("UNSIGNED"): - return match.group(0).upper() + length + " UNSIGNED" - return match.group(0).upper() + length - if data_type in {"INT64", "NUMERIC"}: - return "BIGINT" + self._column_type_length(column_type, 19) + if "UNSIGNED" in self._mysql_integer_type: + return f"{match.group(0).upper()}{length} UNSIGNED" + return f"{match.group(0).upper()}{length}{' UNSIGNED' if unsigned else ''}" if data_type == "BOOLEAN": return "TINYINT(1)" + if data_type.startswith(("REAL", "DOUBLE", "FLOAT", "DECIMAL", "DEC", "FIXED")): + return full_column_type if data_type not in MYSQL_COLUMN_TYPES: return self._mysql_string_type return full_column_type diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/tests/factories.py new/sqlite3-to-mysql-2.1.7/tests/factories.py --- old/sqlite3-to-mysql-2.1.0/tests/factories.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/tests/factories.py 2024-01-13 22:07:22.000000000 +0100 @@ -3,7 +3,10 @@ import factory -from . import models +from . import faker_providers, models + + +factory.Faker.add_provider(faker_providers.DateTimeProviders) class AuthorFactory(factory.Factory): @@ -37,7 +40,7 @@ boolean_field: factory.Faker = factory.Faker("boolean") char_field: factory.Faker = factory.Faker("text", max_nb_chars=255) date_field: factory.Faker = factory.Faker("date_this_decade") - date_time_field: factory.Faker = factory.Faker("date_time_this_century") + date_time_field: factory.Faker = factory.Faker("date_time_this_century_without_microseconds") decimal_field: factory.Faker = factory.Faker("pydecimal", left_digits=8, right_digits=2) float_field: factory.Faker = factory.Faker("pyfloat", left_digits=8, right_digits=4) integer_field: factory.Faker = factory.Faker("pyint", min_value=-(2**31), max_value=2**31 - 1) @@ -53,9 +56,9 @@ small_integer_field: factory.Faker = factory.Faker("pyint", min_value=-(2**15), max_value=2**15 - 1) string_field: factory.Faker = factory.Faker("text", max_nb_chars=255) text_field: factory.Faker = factory.Faker("text", max_nb_chars=1024) - time_field: factory.Faker = factory.Faker("time_object") + time_field: factory.Faker = factory.Faker("time_object_without_microseconds") varchar_field: factory.Faker = factory.Faker("text", max_nb_chars=255) - timestamp_field: factory.Faker = factory.Faker("date_time_this_century") + timestamp_field: factory.Faker = factory.Faker("date_time_this_century_without_microseconds") my_type_field: factory.Faker = factory.Faker("text", max_nb_chars=255) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/tests/faker_providers.py new/sqlite3-to-mysql-2.1.7/tests/faker_providers.py --- old/sqlite3-to-mysql-2.1.0/tests/faker_providers.py 1970-01-01 01:00:00.000000000 +0100 +++ new/sqlite3-to-mysql-2.1.7/tests/faker_providers.py 2024-01-13 22:07:22.000000000 +0100 @@ -0,0 +1,22 @@ +import datetime +from typing import Optional + +from faker.providers import BaseProvider, date_time +from faker.typing import DateParseType + + +class DateTimeProviders(BaseProvider): + def time_object_without_microseconds(self, end_datetime: Optional[DateParseType] = None) -> datetime.time: + return date_time.Provider(self.generator).time_object(end_datetime).replace(microsecond=0) + + def date_time_this_century_without_microseconds( + self, + before_now: bool = True, + after_now: bool = False, + tzinfo: Optional[datetime.tzinfo] = None, + ) -> datetime.datetime: + return ( + date_time.Provider(self.generator) + .date_time_this_century(before_now, after_now, tzinfo) + .replace(microsecond=0) + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/tests/func/test_cli.py new/sqlite3-to-mysql-2.1.7/tests/func/test_cli.py --- old/sqlite3-to-mysql-2.1.0/tests/func/test_cli.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/tests/func/test_cli.py 2024-01-13 22:07:22.000000000 +0100 @@ -1,4 +1,5 @@ import typing as t +from datetime import datetime from random import choice, sample import pytest @@ -10,6 +11,7 @@ from sqlalchemy.engine import Engine, Inspector from sqlite3_to_mysql import SQLite3toMySQL +from sqlite3_to_mysql import __version__ as package_version from sqlite3_to_mysql.cli import cli as sqlite3mysql from tests.conftest import MySQLCredentials @@ -19,12 +21,12 @@ class TestSQLite3toMySQL: def test_no_arguments(self, cli_runner: CliRunner, mysql_database: Engine) -> None: result: Result = cli_runner.invoke(sqlite3mysql) - assert result.exit_code > 0 - assert any( + assert result.exit_code == 0 + assert all( message in result.output for message in { - 'Error: Missing option "-f" / "--sqlite-file"', - "Error: Missing option '-f' / '--sqlite-file'", + f"Usage: {sqlite3mysql.name} [OPTIONS]", + f"{sqlite3mysql.name} version {package_version} Copyright (c) 2018-{datetime.now().year} Klemen Tusar", } ) @@ -538,5 +540,9 @@ sqlite3mysql, arguments, ) + print(result.output) assert result.exit_code == 0 - assert result.output == "" + assert ( + f"{sqlite3mysql.name} version {package_version} Copyright (c) 2018-{datetime.now().year} Klemen Tusar" + in result.output + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/tests/unit/sqlite3_to_mysql_test.py new/sqlite3-to-mysql-2.1.7/tests/unit/sqlite3_to_mysql_test.py --- old/sqlite3-to-mysql-2.1.0/tests/unit/sqlite3_to_mysql_test.py 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/tests/unit/sqlite3_to_mysql_test.py 2024-01-13 22:07:22.000000000 +0100 @@ -39,7 +39,7 @@ with pytest.raises(ValueError) as excinfo: mocker.patch.object(proc, "_valid_column_type", return_value=False) proc._translate_type_from_sqlite_to_mysql("text") - assert "Invalid column_type!" in str(excinfo.value) + assert "is not a valid column_type!" in str(excinfo.value) @pytest.mark.parametrize( "mysql_integer_type, mysql_string_type, mysql_text_type", @@ -103,12 +103,15 @@ assert proc._translate_type_from_sqlite_to_mysql(f"VARCHAR({length})") == re.sub( r"\d+", str(length), proc._mysql_string_type ) - assert proc._translate_type_from_sqlite_to_mysql("DOUBLE PRECISION") == "DOUBLE" + assert proc._translate_type_from_sqlite_to_mysql("DOUBLE PRECISION") == "DOUBLE PRECISION" assert proc._translate_type_from_sqlite_to_mysql("UNSIGNED BIG INT") == "BIGINT UNSIGNED" length = faker.pyint(min_value=1000000000, max_value=99999999999999999999) assert proc._translate_type_from_sqlite_to_mysql(f"UNSIGNED BIG INT({length})") == f"BIGINT({length}) UNSIGNED" - assert proc._translate_type_from_sqlite_to_mysql("INT1") == proc._mysql_integer_type - assert proc._translate_type_from_sqlite_to_mysql("INT2") == proc._mysql_integer_type + assert proc._translate_type_from_sqlite_to_mysql("INT1") == "TINYINT" + assert proc._translate_type_from_sqlite_to_mysql("INT2") == "SMALLINT" + assert proc._translate_type_from_sqlite_to_mysql("INT3") == "MEDIUMINT" + assert proc._translate_type_from_sqlite_to_mysql("INT4") == "INT" + assert proc._translate_type_from_sqlite_to_mysql("INT8") == "BIGINT" length = faker.pyint(min_value=1, max_value=11) assert proc._translate_type_from_sqlite_to_mysql(f"INT({length})") == re.sub( r"\d+", str(length), proc._mysql_integer_type @@ -122,6 +125,102 @@ == f"DECIMAL({precision},{scale})" ) + @pytest.mark.parametrize( + "sqlite_data_type, mysql_data_type", + [ + ("INT", "INT(11)"), + ("INT(5)", "INT(5)"), + ("INT UNSIGNED", "INT(11) UNSIGNED"), + ("INT(5) UNSIGNED", "INT(5) UNSIGNED"), + ("INTEGER", "INT(11)"), + ("TINYINT", "TINYINT"), + ("TINYINT UNSIGNED", "TINYINT UNSIGNED"), + ("TINYINT(4)", "TINYINT(4)"), + ("TINYINT(4) UNSIGNED", "TINYINT(4) UNSIGNED"), + ("SMALLINT", "SMALLINT"), + ("SMALLINT UNSIGNED", "SMALLINT UNSIGNED"), + ("SMALLINT(6)", "SMALLINT(6)"), + ("SMALLINT(6) UNSIGNED", "SMALLINT(6) UNSIGNED"), + ("MEDIUMINT", "MEDIUMINT"), + ("MEDIUMINT UNSIGNED", "MEDIUMINT UNSIGNED"), + ("MEDIUMINT(9)", "MEDIUMINT(9)"), + ("MEDIUMINT(9) UNSIGNED", "MEDIUMINT(9) UNSIGNED"), + ("BIGINT", "BIGINT"), + ("BIGINT UNSIGNED", "BIGINT UNSIGNED"), + ("BIGINT(20)", "BIGINT(20)"), + ("BIGINT(20) UNSIGNED", "BIGINT(20) UNSIGNED"), + ("UNSIGNED BIG INT", "BIGINT UNSIGNED"), + ("INT1", "TINYINT"), + ("INT1 UNSIGNED", "TINYINT UNSIGNED"), + ("INT1(3)", "TINYINT(3)"), + ("INT1(3) UNSIGNED", "TINYINT(3) UNSIGNED"), + ("INT2", "SMALLINT"), + ("INT2 UNSIGNED", "SMALLINT UNSIGNED"), + ("INT2(6)", "SMALLINT(6)"), + ("INT2(6) UNSIGNED", "SMALLINT(6) UNSIGNED"), + ("INT3", "MEDIUMINT"), + ("INT3 UNSIGNED", "MEDIUMINT UNSIGNED"), + ("INT3(9)", "MEDIUMINT(9)"), + ("INT3(9) UNSIGNED", "MEDIUMINT(9) UNSIGNED"), + ("INT4", "INT"), + ("INT4 UNSIGNED", "INT UNSIGNED"), + ("INT4(11)", "INT(11)"), + ("INT4(11) UNSIGNED", "INT(11) UNSIGNED"), + ("INT8", "BIGINT"), + ("INT8 UNSIGNED", "BIGINT UNSIGNED"), + ("INT8(19)", "BIGINT(19)"), + ("INT8(19) UNSIGNED", "BIGINT(19) UNSIGNED"), + ("NUMERIC", "BIGINT(19)"), + ("DOUBLE", "DOUBLE"), + ("DOUBLE UNSIGNED", "DOUBLE UNSIGNED"), + ("DOUBLE(10,5)", "DOUBLE(10,5)"), + ("DOUBLE(10,5) UNSIGNED", "DOUBLE(10,5) UNSIGNED"), + ("DOUBLE PRECISION", "DOUBLE PRECISION"), + ("DOUBLE PRECISION UNSIGNED", "DOUBLE PRECISION UNSIGNED"), + ("DOUBLE PRECISION(10,5)", "DOUBLE PRECISION(10,5)"), + ("DOUBLE PRECISION(10,5) UNSIGNED", "DOUBLE PRECISION(10,5) UNSIGNED"), + ("DECIMAL", "DECIMAL"), + ("DECIMAL UNSIGNED", "DECIMAL UNSIGNED"), + ("DECIMAL(10,5)", "DECIMAL(10,5)"), + ("DECIMAL(10,5) UNSIGNED", "DECIMAL(10,5) UNSIGNED"), + ("REAL", "REAL"), + ("REAL UNSIGNED", "REAL UNSIGNED"), + ("REAL(10,5)", "REAL(10,5)"), + ("REAL(10,5) UNSIGNED", "REAL(10,5) UNSIGNED"), + ("FLOAT", "FLOAT"), + ("FLOAT UNSIGNED", "FLOAT UNSIGNED"), + ("FLOAT(10,5)", "FLOAT(10,5)"), + ("FLOAT(10,5) UNSIGNED", "FLOAT(10,5) UNSIGNED"), + ("DEC", "DEC"), + ("DEC UNSIGNED", "DEC UNSIGNED"), + ("DEC(10,5)", "DEC(10,5)"), + ("DEC(10,5) UNSIGNED", "DEC(10,5) UNSIGNED"), + ("FIXED", "FIXED"), + ("FIXED UNSIGNED", "FIXED UNSIGNED"), + ("FIXED(10,5)", "FIXED(10,5)"), + ("FIXED(10,5) UNSIGNED", "FIXED(10,5) UNSIGNED"), + ("BOOLEAN", "TINYINT(1)"), + ("INT64", "BIGINT(19)"), + ], + ) + def test_translate_type_from_sqlite_to_mysql_all_valid_numeric_columns_signed_unsigned( + self, + sqlite_database: str, + mysql_database: Engine, + mysql_credentials: MySQLCredentials, + sqlite_data_type: str, + mysql_data_type: str, + ) -> None: + proc: SQLite3toMySQL = SQLite3toMySQL( # type: ignore + sqlite_file=sqlite_database, + mysql_user=mysql_credentials.user, + mysql_password=mysql_credentials.password, + mysql_host=mysql_credentials.host, + mysql_port=mysql_credentials.port, + mysql_database=mysql_credentials.database, + ) + assert proc._translate_type_from_sqlite_to_mysql(sqlite_data_type) == mysql_data_type + @pytest.mark.parametrize("quiet", [False, True]) def test_create_database_connection_error( self, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sqlite3-to-mysql-2.1.0/tox.ini new/sqlite3-to-mysql-2.1.7/tox.ini --- old/sqlite3-to-mysql-2.1.0/tox.ini 2023-10-14 13:24:55.000000000 +0200 +++ new/sqlite3-to-mysql-2.1.7/tox.ini 2024-01-13 22:07:22.000000000 +0100 @@ -5,6 +5,7 @@ python3.9, python3.10, python3.11, + python3.12, black, flake8, linters, @@ -16,6 +17,7 @@ 3.9: python3.9 3.10: python3.10 3.11: python3.11 + 3.12: python3.12 [testenv] passenv = ++++++ sqlite3-to-mysql.obsinfo ++++++ --- /var/tmp/diff_new_pack.ujWiG5/_old 2024-01-23 22:57:23.631156528 +0100 +++ /var/tmp/diff_new_pack.ujWiG5/_new 2024-01-23 22:57:23.635156673 +0100 @@ -1,5 +1,5 @@ name: sqlite3-to-mysql -version: 2.1.0 -mtime: 1697282695 -commit: 0a3403e896def960bb608f7366ff2db0d36447af +version: 2.1.7 +mtime: 1705180042 +commit: 06ef89e5bc7592486759266523d9ebb78da52679