Metadata-Version: 2.1
Name: sqlalchemy-helpers
Version: 0.9.0
Summary: SQLAlchemy Helpers
Home-page: http://github.com/fedora-infra/sqlalchemy-helpers
License: LGPL-3.0-or-later
Keywords: database,web,fedora
Author: Fedora Infrastructure
Author-email: admin@fedoraproject.org
Requires-Python: >=3.6.2,<4.0.0
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Database
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Provides-Extra: docs
Provides-Extra: flask
Requires-Dist: Flask (>=2.0,<3.0); extra == "flask"
Requires-Dist: SQLAlchemy (>=1.3.0)
Requires-Dist: alembic (>=1.6.5)
Requires-Dist: myst-parser (>=0.16.1,<0.17.0); extra == "docs"
Requires-Dist: sphinx (>=4,<5); extra == "docs"
Project-URL: Repository, http://github.com/fedora-infra/sqlalchemy-helpers
Description-Content-Type: text/markdown

# SQLAlchemy Helpers

This project contains a tools to use SQLAlchemy and Alembic in a project.

It has a Flask integration, and other framework integrations could be added in
the future.

The full documentation is [on ReadTheDocs](https://sqlalchemy-helpers.readthedocs.io>).

You can install it [from PyPI](https://pypi.org/project/sqlalchemy-helpers/).

![PyPI](https://img.shields.io/pypi/v/sqlalchemy-helpers.svg)
![Supported Python versions](https://img.shields.io/pypi/pyversions/sqlalchemy-helpers.svg)
![Tests status](https://github.com/fedora-infra/sqlalchemy-helpers/actions/workflows/tests.yml/badge.svg?branch=develop)
![Documentation](https://readthedocs.org/projects/sqlalchemy-helpers/badge/?version=latest)

## Flask integration

This is how you can use the Flask integration.

First, create a python module to instanciate the `DatabaseExtension`, and
re-export some useful helpers:

```python
# database.py

from sqlalchemy_helpers import Base, get_or_create, is_sqlite, exists_in_db
from sqlalchemy_helpers.flask_ext import DatabaseExtension, get_or_404, first_or_404

db = DatabaseExtension()
```

In the application factory, import the instance and call its `.init_app()` method:

```python
# app.py

from flask import Flask
from sqlalchemy_helpers.database import db

def create_app():
    """See https://flask.palletsprojects.com/en/1.1.x/patterns/appfactories/"""

    app = Flask(__name__)

    # Load the optional configuration file
    if "FLASK_CONFIG" in os.environ:
        app.config.from_envvar("FLASK_CONFIG")

    # Database
    db.init_app(app)

    return app
```

You can declare your models as you usually would with SQLAlchemy, just inherit
from the `Base` class that you re-exported in `database.py`:

```python
# models.py

from sqlalchemy import Column, Integer, Unicode

from .database import Base


class User(Base):

    __tablename__ = "users"

    id = Column("id", Integer, primary_key=True)
    name = Column(Unicode(254), index=True, unique=True, nullable=False)
    full_name = Column(Unicode(254), nullable=False)
    timezone = Column(Unicode(127), nullable=True)
```

In your views, you can use the instance's `session` property to access the
SQLAlchemy session object. There are also functions to ease classical view
patters such as getting an object by ID or returning a 404 error if not found.

```python
# views.py

from .database import db, get_or_404
from .models import User


@bp.route("/")
def root():
    users = db.session.query(User).all()
    return render_template("index.html", users=users)


@bp.route("/user/<int:user_id>")
def profile(user_id):
    user = get_or_404(User, user_id)
    return render_template("profile.html", user=user)
```

You can adjust alembic's `env.py` file to get the database URL from you app's
configuration:

```python
# migrations/env.py

from my_flask_app.app import create_app
from my_flask_app.database import Base
from sqlalchemy_helpers.flask_ext import get_url_from_app

url = get_url_from_app(create_app)
config.set_main_option("sqlalchemy.url", url)
target_metadata = Base.metadata

# ...rest of the env.py file...
```

Also set `script_location` in you alembic.ini file in order to use it with the
`alembic` command-line tool:

```python
# migrations/alembic.ini

[alembic]
script_location = %(here)s
```

### Full example

In Fedora Infrastructure we use [a cookiecutter
template](https://github.com/fedora-infra/cookiecutter-flask-webapp/) that
showcases this Flask integration, feel free to check it out or even use it if
it suits your needs.

