Skip to main content

An async database toolkit.

Project description

Aerie

A sweat wrapper around SQLAlchemy made to support asynchronous workloads.

Aerie - is an avariel (or winged elf) from Baldur's Gate II game.

PyPI GitHub Workflow Status GitHub Libraries.io dependency status for latest release PyPI - Downloads GitHub Release Date Lines of code

Installation

Install aerie using PIP or poetry:

pip install aerie[postgresql]
# or
poetry add aerie[postgresql]

For SQLite use "sqlite" extra. To install all drivers use "full" extra.

Features

  • full async/await support
  • plain SQL with bound params
  • SQLAlchemy query builders support
  • SQLAlchemy ORM support
  • pagination

TODO

  • simplify column definition: sa.Column(sa.Integer) -> models.IntergerField()
  • enhance DbSession with executable API: await session.query(User).where(User.id == 1).one_or_none()
  • integrate with Alembic CLI
  • multiple metadata support (for multiple distinct databasees)

Quick start

See example application in examples/ directory of this repository.

Usage

As this library is based on SQLAlchemy, it is strictly recommended getting yourself familiar with it.

A general usage is:

  • create an instance of Aerie
  • define ORM models
  • create tables in the database (or, preferably, use Alembic migrations)
  • obtain a session and perform database queries

Aerie instance

Create an instance of Aerie class and pass a connection string to it:

from aerie import Aerie

db = Aerie('sqlite+aiosqlite:///tmp/database.sqlite2')
# or
db = Aerie('postgresql+asyncpg://postgres:postgres@localhost/aerie')

You need appropriate driver installed. Add "aiosqlite" for SQLite support, or add "asyncpg" for PostreSQL support.

Raw SQL queries

At this step Aerie is ready to work. Create a new transaction and execute any query you need.

from sqlalchemy.sql import text

async with db.transaction() as tx:
    # assuming "users" table exists
    sql = text('select * from users where user_id = :user_id')
    rows = await tx.execute(sql, {'user_id': 1})

Full listing examples/raw_sql.py

Using query builder

Sure, you are not limited to plain SQL. SQLAlchemy query builders also supported (because Aerie is a tiny layer on top of the SQLAlchemy)

from sqlalchemy.sql import text
import sqlalchemy as sa
from aerie import metadata

users = sa.Table(
    'users', metadata,
    sa.Column(sa.Integer, name='id', primary_key=True),
    sa.Column(sa.String, name='name'),
)

# create tables
await db.create_tables()

async with db.transaction() as tx:
    stmt = select(users).where(users.c.id == 2)
    rows = await tx.execute(stmt)

Full listing examples/tables.py

Using ORM models and sessions

Another option to low-level query builder are ORM models. Aerie provides aerie.Model class that you should extend to create your model.

from aerie import Model
import sqlalchemy as sa


class User(Model):
    __tablename__ = 'users'

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String)


# create tables
await db.create_tables()

async with db.session() as session:
    session.add_all([
        User(id=1, name='One'),
        User(id=2, name='Two'),
        User(id=3, name='Three'),
    ])
    await session.flush()

    # get first user in the row set
    stmt = session.select(User)
    user = await session.first(stmt)

Make sure the module with models is imported before you create tables. Otherwise they will not be added to the metadata and, thus, not created.

Full listing examples/orm.py

Pagination

Aerie's DbSession ships with pagination utilities out of the box. When you need to paginate a query just call DbSession.paginate method.

async with db.session() as session:
    stmt = session.select(User)
    page = await session.paginate(stmt, page=1, page_size=10)

    for user in page:
        print(user)
        print('Next page: %s' % page.next_page)
        print('Previous page: %s' % page.previous_page)
        print('Displaying items: %s - %s' % (page.start_index, page.end_index))

The page object has more helper attributes:

Property Type Description
total_pages int Total pages in the row set.
has_next bool Test if the next page is available.
has_previous bool Test if the previous page is available.
next_page int Next page number. Always returns an integer. If there is no more pages the current page number returned.
previous_page int Previous page number. Always returns an integer. If there is no previous page, the number 1 returned.
start_index int The 1-based index of the first item on this page.
end_index int The 1-based index of the last item on this page.
total_rows int Total rows in result set.

Alembic migrations

Alembic usage is well documented in the official docs: Using Asyncio with Alembic

Note, you need to use aerie.metadata when you configure target_metadata option:

# migrations/env.py

from aerie import metadata

...

target_metadata = metadata

...

Also, don't forget to import all your models in Alembic's env.py file so their structure is fully loaded and no models forgotten.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aerie-0.2.0.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aerie-0.2.0-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

Details for the file aerie-0.2.0.tar.gz.

File metadata

  • Download URL: aerie-0.2.0.tar.gz
  • Upload date:
  • Size: 8.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.9 CPython/3.9.7 Linux/5.8.0-1041-azure

File hashes

Hashes for aerie-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b44a24f58b4a7bc898185c09fa2995a76633c652268a6c5cf2d4cc71dcbab231
MD5 6c309cc88fbc2dc3f09b6a506a102815
BLAKE2b-256 b38f55876ad6c843ff0ef2efb173b12fbe11c3c17a51b27199c1fa96cb191f08

See more details on using hashes here.

File details

Details for the file aerie-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: aerie-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 7.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.9 CPython/3.9.7 Linux/5.8.0-1041-azure

File hashes

Hashes for aerie-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0950f47b214d7694c1e2a20e3c730bff51290b0aee885a4c31069a85cf1beb43
MD5 83dea7eb4b51c6d61a435c1ac45fc4f2
BLAKE2b-256 558807528385270ee30f07041dacc6f0b0cf2d39d71a6f8365ef7755b205a000

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page