From afbfd95273c51d6a14174e9e07fb63ed2a34f72a Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Sun, 5 Jul 2026 16:00:52 -0700 Subject: [PATCH] Remove sqlean.py support (#772) Closes #771, refs #769 --- .github/workflows/test.yml | 3 --- docs/changelog.rst | 1 + docs/installation.rst | 10 +++++----- docs/python-api.rst | 2 +- mypy.ini | 3 --- sqlite_utils/utils.py | 11 +++-------- tests/test_gis.py | 8 -------- 7 files changed, 10 insertions(+), 28 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7e1e953..d85cbf8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,9 +31,6 @@ jobs: - name: Install SpatiaLite if: matrix.os == 'ubuntu-latest' run: sudo apt-get install libsqlite3-mod-spatialite - - name: On macOS with Python 3.10 test with sqlean.py - if: matrix.os == 'macos-latest' && matrix.python-version == '3.10' - run: pip install sqlean.py sqlite-dump - name: Build extension for --load-extension test if: matrix.os == 'ubuntu-latest' run: |- diff --git a/docs/changelog.rst b/docs/changelog.rst index f6a8ea2..7efeb95 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -12,6 +12,7 @@ Unreleased Breaking changes: - ``table.foreign_keys`` now returns ``ForeignKey`` objects that are dataclasses rather than ``namedtuple`` instances, so they can no longer be unpacked or indexed as ``(table, column, other_table, other_column)`` tuples - access their fields by name instead. Compound (multi-column) foreign keys are now represented as a single ``ForeignKey`` with ``is_compound=True`` and populated ``columns``/``other_columns`` tuples, where ``column`` and ``other_column`` are ``None``. Previously they were returned as one ``ForeignKey`` per column, misleadingly suggesting several independent foreign keys. See :ref:`upgrading_3_to_4` for details. (:issue:`594`) +- Removed support for using ``sqlean.py`` as a drop-in replacement for the Python standard library ``sqlite3`` module. ``sqlite-utils`` will now use ``pysqlite3`` if it is installed, otherwise it will use ``sqlite3`` from the standard library. Compound foreign key support: diff --git a/docs/installation.rst b/docs/installation.rst index beb6d4a..1333f5d 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -52,15 +52,15 @@ On some platforms the ability to load additional extensions (via ``conn.load_ext You may also see the error ``sqlite3.OperationalError: table sqlite_master may not be modified`` when trying to alter an existing table. -You can work around these limitations by installing either the `pysqlite3 `__ package or the `sqlean.py `__ package, both of which provide drop-in replacements for the standard library ``sqlite3`` module but with a recent version of SQLite and full support for loading extensions. +You can work around these limitations by installing the `pysqlite3 `__ package, which provides a drop-in replacement for the standard library ``sqlite3`` module but with a recent version of SQLite and full support for loading extensions. -To install ``sqlean.py`` (which has compiled binary wheels available for all major platforms) run the following: +To install ``pysqlite3`` run the following: .. code-block:: bash - sqlite-utils install sqlean.py + sqlite-utils install pysqlite3 -``pysqlite3`` and ``sqlean.py`` do not provide implementations of the ``.iterdump()`` method. To use that method (see :ref:`python_api_itedump`) or the ``sqlite-utils dump`` command you should also install the ``sqlite-dump`` package: +``pysqlite3`` does not provide an implementation of the ``.iterdump()`` method. To use that method (see :ref:`python_api_itedump`) or the ``sqlite-utils dump`` command you should also install the ``sqlite-dump`` package: .. code-block:: bash @@ -87,4 +87,4 @@ For ``zsh``: Add this code to ``~/.zshrc`` or ``~/.bashrc`` to automatically run it when you start a new shell. -See `the Click documentation `__ for more details. \ No newline at end of file +See `the Click documentation `__ for more details. diff --git a/docs/python-api.rst b/docs/python-api.rst index a33b256..6723efb 100644 --- a/docs/python-api.rst +++ b/docs/python-api.rst @@ -2184,7 +2184,7 @@ The ``db.iterdump()`` method returns a sequence of SQL strings representing a co This uses the `sqlite3.Connection.iterdump() `__ method. -If you are using ``pysqlite3`` or ``sqlean.py`` the underlying method may be missing. If you install the `sqlite-dump `__ package then the ``db.iterdump()`` method will use that implementation instead: +If you are using ``pysqlite3`` the underlying method may be missing. If you install the `sqlite-dump `__ package then the ``db.iterdump()`` method will use that implementation instead: .. code-block:: bash diff --git a/mypy.ini b/mypy.ini index de0dc83..2f6a875 100644 --- a/mypy.ini +++ b/mypy.ini @@ -16,9 +16,6 @@ ignore_errors = True [mypy-pysqlite3.*] ignore_missing_imports = True -[mypy-sqlean.*] -ignore_missing_imports = True - [mypy-sqlite_dump.*] ignore_missing_imports = True diff --git a/sqlite_utils/utils.py b/sqlite_utils/utils.py index 0ca98fc..865ee79 100644 --- a/sqlite_utils/utils.py +++ b/sqlite_utils/utils.py @@ -43,15 +43,10 @@ else: dbapi2 = importlib.import_module("pysqlite3.dbapi2") OperationalError = dbapi2.OperationalError except ImportError: - try: - sqlite3 = importlib.import_module("sqlean") - dbapi2 = importlib.import_module("sqlean.dbapi2") - OperationalError = dbapi2.OperationalError - except ImportError: - import sqlite3 # noqa: F401 - from sqlite3 import dbapi2 # noqa: F401 + import sqlite3 # noqa: F401 + from sqlite3 import dbapi2 # noqa: F401 - OperationalError = dbapi2.OperationalError + OperationalError = dbapi2.OperationalError SPATIALITE_PATHS = ( diff --git a/tests/test_gis.py b/tests/test_gis.py index 1b5ed70..e8f4c08 100644 --- a/tests/test_gis.py +++ b/tests/test_gis.py @@ -6,11 +6,6 @@ from sqlite_utils.cli import cli from sqlite_utils.db import Database from sqlite_utils.utils import find_spatialite, sqlite3 -try: - import sqlean # type: ignore[import-not-found] -except ImportError: - sqlean = None - pytestmark = [ pytest.mark.skipif( @@ -20,9 +15,6 @@ pytestmark = [ not hasattr(sqlite3.Connection, "enable_load_extension"), reason="sqlite3.Connection missing enable_load_extension", ), - pytest.mark.skipif( - sqlean is not None, reason="sqlean.py is not compatible with SpatiaLite" - ), ]