Обратите внимание на круглые скобки в операции, которая занимает несколько строк в предыдущем примере. Структура метода Table() совпадает со структурой таблицы. Поскольку наша таблица содержит три графы, в методе Table() расположены три вызова метода Column().
zoo представляет собой некий волшебный объект, который соединяет мир баз данных SQL и мир структур данных Python.
Запишите в таблицу данные с помощью новых функций языка выражений:
… conn.execute(zoo.insert(('bear', 2, 1000.0)))
>>> conn.execute(zoo.insert(('weasel', 1, 2000.0)))
>>> conn.execute(zoo.insert(('duck', 10, 0)))
Далее создадим оператор SELECT (zoo.select() делает выборку всего, что содержится в таблице, представленной объектом zoo, как это сделала бы инструкция SELECT * FROM zoo в простом SQL):
>>> result = conn.execute(zoo.select())
Наконец, получим результат:
>>> rows = result.fetchall()
>>> print(rows)
[('bear', 2, 1000.0), ('weasel', 1, 2000.0), ('duck', 10, 0.0)]
В предыдущем разделе объект zoo являлся промежуточным звеном между SQL и Python. В самом верхнем слое SQLAlchemy объектно-реляционное отображение (Object-Relational Mapper, ORM) использует язык выражений SQL, но старается сделать реальные механизмы базы данных невидимыми. Вы определяете классы, а ORM обрабатывает способ, с помощью которого они получают данные из базы данных и возвращают их обратно. Основная идея, на которой базируется сложный термин «объектно-реляционное отображение», заключается в том, что вы можете ссылаться на объекты в своем коде и поэтому придерживаться принципов работы с Python, но при этом использовать реляционную базу данных.
Мы определим класс Zoo и свяжем его с ORM. В этот раз укажем SQLite использовать файл zoo.db, чтобы убедиться, что ORM работает.
Как и в предыдущих двух разделах, следующие сниппеты являются частью одной программы, разбитой на фрагменты, которые я объясню. Не переживайте, если чего-то не поймете. В документации к SQLAlchemy содержатся все необходимые детали, работа с SQLALchemy может оказаться довольно сложной. Я хочу показать вам, что нужно сделать, чтобы ORM работал, чтобы вы могли определить, какой из подходов, рассмотренных в этой главе, годится для вас больше других.
Импорт остается неизменным, но в этот раз нам нужно кое-что еще:
>>> import sqlalchemy as sa
>>> from sqlalchemy.ext.declarative import declarative_base
Вот так создается соединение:
>>> conn = sa.create_engine('sqlite:///zoo.db')
Теперь мы начинаем работать с SQLAlchemy ORM. Определяем класс Zoo и связываем его атрибуты с графами таблицы:
>>> Base = declarative_base()
>>> class Zoo(Base):
…·····__tablename__ = 'zoo'
…·····critter = sa.Column('critter', sa.String, primary_key=True)
…·····count = sa.Column('count', sa.Integer)
…·····damages = sa.Column('damages', sa.Float)
…·····def __init__(self, critter, count, damages):
…·········self.critter = critter
…·········self.count = count
…·········self.damages = damages
…·····def __repr__(self):
…·········return "
Следующая строка как по волшебству создает базу данных и таблицу:
>>> Base.metadata.create_all(conn)
Вы можете добавить в таблицу данные путем создания объектов Python. ORM управляет данными изнутри:
>>> first = Zoo('duck', 10, 0.0)
>>> second = Zoo('bear', 2, 1000.0)
>>> third = Zoo('weasel', 1, 2000.0)
>>> first
Далее мы указываем ORM отвезти нас в страну SQL. Создаем сессию, чтобы беседовать с базой данных:
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=conn)
>>> session = Session()
Внутри сессии записываем три созданных нами объекта в базу данных. Функция add() добавляет один объект, а функция add_all() добавляет список:
>>> session.add(first)
>>> session.add_all([second, third])
Наконец, нам нужно завершить сессию:
>>> session.commit()