Выпустил новую версию aiopg 0.2 -- библиотеки для работы с PostgreSQL из asyncio.
aiopg использует асинхронные вызовы и в этом похож на txpostgres и momoko -- библиотеки для работы с PostgreSQL под twisted и tornado соответственно.
В новой версии aiopg появилась опциональная поддержка SQLAlchemy Core Expressions.
Проще один раз показать.
Создаем описание структуры базы данных:
import sqlalchemy as sa
metadata = sa.MetaData()
users = sa.Table('users', metadata,
                 sa.Column('id', sa.Integer, primary_key=True),
                 sa.Column('name', sa.String(255)),
                 sa.Column('birthday', sa.DateTime))
emails = sa.Table('emails', metadata,
                  sa.Column('id', sa.Integer, primary_key=True),
                  sa.Column('user_id', None, sa.ForeignKey('users.id')),
                  sa.Column('email', sa.String(255), nullable=False),
                  sa.Column('private', sa.Boolean, nullable=False))
Как видите -- две таблицы, связанные отношением один-ко-многим. Для тех, кто не знаком -- алхимия позволяет описать любую модель данных, которая только может прийти в голову. Индексы, constraints, пользовательские типы данных такие как array и hstore -- тоже.
Теперь нужно сделать engine:
from aiopg.sa import create_engine
engine = yield from create_engine(user='aiopg',
                                  database='aiopg',
                                  host='127.0.0.1',
                                  password='passwd')
engine содержит внутри connection pool.
Для работы с БД нужно получить connection и что-нибудь выполнить:
with (yield from engine) as conn:
    uid = yield from conn.scalar(
        users.insert().values(name='Andrew', birthday=datetime(1978, 12, 9)))
Обратите внимание: диалект знает о INSERT ... RETURNING и позвращает
primary key для вставляемой записи.
Работа с транзакциями:
with (yield from engine) as conn:
    tr = yield from conn.begin()
    # Do something
    yield from tr.commit()
Получение данных:
with (yield from engine) as conn:
    res = yield from conn.execute(users.select())
    for row in res:
        print(res)
Сложный запрос:
with (yield from engine) as conn:
    join = sa.join(emails, users, users.c.id == emails.c.user_id)
    query = (sa.select([users.c.name])
             .select_from(join)
             .where(emails.c.private == 0)
             .group_by(users.c.name)
             .having(sa.func.count(emails.c.private) > 0))
    print("Users with public emails:")
    ret = yield from conn.execute(query)
    for row in ret:
        print(row.name)
Вызов SQL функций:
with (yield from engine) as conn:
    query = (sa.select([sa.func.avg(sa.func.age(users.c.birthday))])
             .select_from(users))
    ave = (yield from conn.scalar(query))
    print("Average age of population is", ave,
          "or ~", int(ave.days / 365), "years")
sa.func.avg и sa.func.age выполняются на стороне SQL сервера.
Не понятно как подключить к проекту орм с использованием асинхронного создания моделей на этапе инициализации проекта.
ОтветитьУдалить