Metadata-Version: 2.1
Name: Flask-SQLAlchemy-compat
Version: 0.2.1
Summary: Support the compatibility between Flask-SQLAlchemy and Flask-SQLAlchemy-Lite.
Author-email: Yuchen Jin <cainmagi@gmail.com>
Maintainer-email: Yuchen Jin <cainmagi@gmail.com>
License: MIT License
Project-URL: Homepage, https://github.com/cainmagi/flask-sqlalchemy-compat
Project-URL: Documentation, https://cainmagi.github.io/flask-sqlalchemy-compat/
Project-URL: Repository, https://github.com/cainmagi/flask-sqlalchemy-compat.git
Project-URL: Issues, https://github.com/cainmagi/flask-sqlalchemy-compat/issues
Project-URL: Changelog, https://github.com/cainmagi/flask-sqlalchemy-compat/blob/main/Changelog.md
Keywords: python,python3,python-library,flask,sqlalchemy,flask-sqlalchemy,flask-sqlalchemy-lite,compatibility,compatibility-layer
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Framework :: Flask
Classifier: Topic :: Database :: Front-Ends
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: flask[async]
Requires-Dist: sqlalchemy[asyncio]>=2.0.31; python_version >= "3.13"
Requires-Dist: sqlalchemy[asyncio]>=2.0.16; python_version >= "3.8" and python_version < "3.13"
Requires-Dist: sqlalchemy[asyncio]>=2.0.0; python_version < "3.8"
Requires-Dist: werkzeug
Requires-Dist: typing-extensions>=4.1.0
Provides-Extra: dev
Requires-Dist: flask-sqlalchemy-lite; python_version >= "3.9" and extra == "dev"
Requires-Dist: flask-sqlalchemy>=3.1.0; python_version >= "3.8" and extra == "dev"
Requires-Dist: flask-sqlalchemy-compat-backend-py37; python_version < "3.8" and extra == "dev"
Requires-Dist: flask-migrate; extra == "dev"
Requires-Dist: flask-alembic; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: flake8-black; extra == "dev"
Requires-Dist: importlib-metadata; python_version < "3.8" and extra == "dev"
Requires-Dist: packaging; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: wheel; extra == "dev"
Provides-Extra: backends
Requires-Dist: flask-sqlalchemy-lite; python_version >= "3.9" and extra == "backends"
Requires-Dist: flask-sqlalchemy>=3.1.0; python_version >= "3.8" and extra == "backends"
Requires-Dist: flask-sqlalchemy-compat-backend-py37; python_version < "3.8" and extra == "backends"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-base-url; extra == "test"
Requires-Dist: pytest-flask; extra == "test"
Requires-Dist: pytest-html; extra == "test"
Requires-Dist: pytest-metadata; extra == "test"
Requires-Dist: py; extra == "test"
Requires-Dist: pytest-variables; extra == "test"
Requires-Dist: pytest-xdist; extra == "test"
Requires-Dist: flask-login; extra == "test"
Provides-Extra: example
Requires-Dist: flask-login; extra == "example"

# Flask SQLAlchemy Compat

<p><img alt="Banner" src="https://repository-images.githubusercontent.com/900959960/5fa49b35-0f23-4e6d-9c00-b57ff6e513fd"></p>

<p align="center">
  <a href="https://github.com/cainmagi/flask-sqlalchemy-compat/releases/latest"><img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/cainmagi/flask-sqlalchemy-compat?logo=github&sort=semver&style=flat-square"></a>
  <a href="https://github.com/cainmagi/flask-sqlalchemy-compat/releases"><img alt="GitHub all releases" src="https://img.shields.io/github/downloads/cainmagi/flask-sqlalchemy-compat/total?logo=github&style=flat-square"></a>
  <a href="https://github.com/cainmagi/flask-sqlalchemy-compat/blob/main/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/cainmagi/flask-sqlalchemy-compat?style=flat-square&logo=opensourceinitiative&logoColor=white"></a>
  <a href="https://pypi.org/project/flask-sqlalchemy-compat"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dm/flask-sqlalchemy-compat?style=flat-square&logo=pypi&logoColor=white&label=pypi"/></a>
</p>
<p align="center">
  <a href="https://github.com/cainmagi/flask-sqlalchemy-compat/actions/workflows/python-package.yml"><img alt="GitHub Actions (Build)" src="https://img.shields.io/github/actions/workflow/status/cainmagi/flask-sqlalchemy-compat/python-package.yml?style=flat-square&logo=githubactions&logoColor=white&label=build"></a>
  <a href="https://github.com/cainmagi/flask-sqlalchemy-compat/actions/workflows/python-publish.yml"><img alt="GitHub Actions (Release)" src="https://img.shields.io/github/actions/workflow/status/cainmagi/flask-sqlalchemy-compat/python-publish.yml?style=flat-square&logo=githubactions&logoColor=white&label=release"></a>
</p>

Support the compatibility between `flask_sqlalchemy` and `flask_sqlalchemy_lite`. It allows users to make minimal changes when they need to migrate from either one of these two packages to each other.

The main motivation of this package is because `flask_sqlalchemy_lite` does not support `python<=3.8`. This package is designed for providing the similar usages when users have to make the `flask_sqlalchemy_lite` working with `python<=3.8` by using `flask_sqlalchemy`. In this case, users can get rid of the difficulty of maintaining two sets of codes.

> [!WARNING]
> This package is designed for `sqlalchemy>=2.0.0` only. If you are using an older version. You cannot use this package.

> [!WARNING]
> To make this package work with `python=3.7`, users should install an unofficial `flask-sqlalchemy` version.

## 1. Install

Intall the **latest released version** of this package by using the PyPI source:

``` sh
python -m pip install flask-sqlalchemy-compat
```

or use the following commands to install **the developing version** from the GitHub Source when you have already installed [Git :hammer:][tool-git]:

```sh
python -m pip install "flask-sqlalchemy-compat[dev] @ git+https://github.com/cainmagi/flask-sqlalchemy-compat.git"
```

> [!WARNING]
> To make this package work with `python=3.7`, users should install an unofficial `flask-sqlalchemy` version. See
>
> https://github.com/pallets-eco/flask-sqlalchemy/issues/1140#issuecomment-1577921154
>
> This unofficial version can be installed by:
> ```sh
> python -m pip install flask-sqlalchemy-compat[backends]
> ```

## 2. Usage

When you are using `flask-sqlalchemy-lite`, using the following codes will let your codes fall back to the compatible mode if `flask-sqlalchemy-lite` is not installed but `flask-sqlalchemy` is installed.

```python
import sqlalchemy as sa
import sqlalchemy.orm as sa_orm
import flask_sqlalchemy_compat as fsc


class _Base(sa_orm.DeclarativeBase): ...


db, Base = fsc.get_flask_sqlalchemy_lite(_Base)


class NewModel(Base):
    __tablename__ = "new_model"

    id: sa_orm.Mapped[int] = sa_orm.mapped_column(primary_key=True)
    name: sa_orm.Mapped[str] = sa_orm.mapped_column()


if __name__ == "__main__":
    import os
    import flask

    app = flask.Flask(__name__, instance_path=os.path.abspath("./instance"))
    app.config.update({"SQLALCHEMY_ENGINES": {"default": "sqlite:///main.db"}})
    db.init_app(app)

    with app.app_context():
        Base.metadata.create_all(db.engine)

        db.session.add(NewModel(name="new"))
        db.session.commit()

        model = db.session.scalar(sa.select(NewModel))
        print(model.id, model.name) if model is not None else print("NOT FOUND.")
```

The above codes will works no matter `flask_sqlalchemy_lite` or `flask_sqlalchemy` is installed.

Similarly, the following example is designed for the codes written with `flask_sqlalchemy`. The codes fall back to the compatible mode if `flask-sqlalchemy` is not installed but `flask-sqlalchemy-lite` is installed.

```python
import sqlalchemy as sa
import sqlalchemy.orm as sa_orm
import flask_sqlalchemy_compat as fsc


class _Base(sa_orm.DeclarativeBase): ...


db = fsc.get_flask_sqlalchemy(_Base)


class NewModel(db.Model):
    id: sa_orm.Mapped[int] = sa_orm.mapped_column(primary_key=True)
    name: sa_orm.Mapped[str] = sa_orm.mapped_column()


if __name__ == "__main__":
    import os
    import flask

    app = flask.Flask(__name__, instance_path=os.path.abspath("./instance"))
    app.config.update({"SQLALCHEMY_DATABASE_URI": "sqlite:///main.db"})
    db.init_app(app)

    with app.app_context():
        db.create_all()

        # Indeed, flask_sqlalchemy has a type hint issue until `3.1.x`.
        # But it does not cause issues in run time. See
        # https://github.com/pallets-eco/flask-sqlalchemy/issues/1312
        db.session.add(NewModel(name="new"))
        db.session.commit()

        model = db.session.scalar(sa.select(NewModel))
        print(model.id, model.name) if model is not None else print("NOT FOUND.")
```

The magic happens if you run the first example with only `flask-sqlalchemy` installed and the second example with only `flask-sqlalchemy-lite` installed.

Compared to the above minimal examples, we also provided a `usage.py` file and example applications in the `examples/` folder. Check them to view more details.

> [!TIP]
> To run the demos in `examples`, you need to install the optional dependencies by
> ```sh
> python -m pip install flask-sqlalchemy-compat[example,backends]
> ```

## 3. Documentation

Check the documentation to find more details about the examples and APIs.

https://cainmagi.github.io/flask-sqlalchemy-compat/

## 4. Contributing

See [CONTRIBUTING.md :book:][link-contributing]

## 5. Changelog

See [Changelog.md :book:][link-changelog]

[tool-git]:https://git-scm.com/downloads

[link-contributing]:https://github.com/cainmagi/flask-sqlalchemy-compat/blob/main/CONTRIBUTING.md
[link-changelog]:https://github.com/cainmagi/flask-sqlalchemy-compat/blob/main/Changelog.md
