Рубрики
Без рубрики

Еще один пошаговый учебник SQLalchemy (часть 2 из 2)

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

В первой части этой серии мы пошли, что некоторые могут вызвать метод «SQL-выражения SQL» использования SQLALCHMEY, чтобы взаимодействовать с вашей базой данных. Теория за этим заключается в том, что мы должны учиться менее абстрактным способом делать вещи, прежде чем добраться до более высокого уровня (и более абстрактных) методов. Это верно во многих математических классах, таких как исчисление, в котором вы изучаете долгий путь, чтобы найти стандартное отклонение некоторых калитков, прежде чем узнать о ярлыке.

На второй половину мы будем делать то, что может сказать, это простой способ использовать SQLALCHEMY. Это известен как метод «Объект реляционного» и Официальная документация на самом деле начинается с этого. Эта методология изначально занимает немного больше времени, но во многих отношениях также намного проще следовать.

Привыкание к отображениям данных

Старая школа Робина Мунна Учебное пособие SQLALCHEMY Вызывается этот раздел «Картирование данных», потому что мы будем отображать данные в базе данных на классы Python. Давайте начнем!

from sqlalchemy import create_engine
from sqlalchemy import Column, MetaData, Table
from sqlalchemy import Integer, String, ForeignKey
from sqlalchemy.orm import mapper, sessionmaker

####################################################
class User(object):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, name, fullname, password):
        """Constructor"""
        self.name = name
        self.fullname = fullname
        self.password = password
        
    def __repr__(self):
        return "" % (self.name, self.fullname, self.password)
        
# create a connection to a sqlite database
# turn echo on to see the auto-generated SQL
engine = create_engine("sqlite:///tutorial.db", echo=True)

# this is used to keep track of tables and their attributes
metadata = MetaData()
users_table = Table('users', metadata,
                    Column('user_id', Integer, primary_key=True),
                    Column('name', String),
                    Column('fullname', String),
                    Column('password', String)
                    )
email_table = Table('email', metadata,
                    Column('email_id', Integer, primary_key=True),
                    Column('email_address', String),
                    Column('user_id', Integer, ForeignKey('users.user_id'))
                    )

# create the table and tell it to create it in the 
# database engine that is passed
metadata.create_all(engine)

# create a mapping between the users_table and the User class
mapper(User, users_table)

Первое отличие, чтобы принять к сведению по сравнению с нашими предыдущими примерами, это Пользователь класс. Мы изменили наш оригинальный пример (см. Часть) немного, чтобы соответствовать тому, что на официальной документации, а именно параметры теперь имеются, полное имя и пароль. Остальные должны выглядеть одинаково, пока не доберемся до Mapper утверждение. Этот удобный метод позволяет SQLALCHEMY для отображения пользовательского класса пользователей_табели. Это может показаться не иметь большого значения, но этот метод делает добавление пользователей в базу данных гораздо более простым.

Однако, прежде чем мы доберемся до этого, нам нужно обсудить Декларативный конфигурационный стиль Отказ Хотя стиль выше дает нам гранулированный контроль над столом, Mapper и Class, по большей части нам не нужно, чтобы быть таким сложным. Вот где приходит декларативный стиль. Это делает настройку всего еще проще. Первый декларативный стиль, который я знал, было дополнением для SQLALCHEMY, называемой Эликсир Отказ Этот встроенный декларативный стиль не так полно, как эликсир, но он укормит, потому что у вас нет дополнительной зависимости. Давайте посмотрим, насколько декларативно отличается:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref, mapper, relation, sessionmaker

Base = declarative_base()

########################################################################
class User(Base):
    """"""
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    password = Column(String)

    #----------------------------------------------------------------------
    def __init__(self, name, fullname, password):
        """Constructor"""
        self.name = name
        self.fullname = fullname
        self.password = password
        
    def __repr__(self):
        return "" % (self.name, self.fullname, self.password)
        
########################################################################
class Address(Base):
    """
    Address Class
    
    Create some class properties before initilization
    """
    __tablename__ = "addresses"
    id = Column(Integer, primary_key=True)
    email_address = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'))
    
    # creates a bidirectional relationship
    # from Address to User it's Many-to-One
    # from User to Address it's One-to-Many
    user = relation(User, backref=backref('addresses', order_by=id))

    #----------------------------------------------------------------------
    def __init__(self, email_address):
        """Constructor"""
        self.email_address = email_address
        
    def __repr__(self):
        return "" % self.email_address
    
    
# create a connection to a sqlite database
# turn echo on to see the auto-generated SQL
engine = create_engine("sqlite:///tutorial.db", echo=True)

# get a handle on the table object
users_table = User.__table__
# get a handle on the metadata
metadata = Base.metadata
metadata.create_all(engine)

Как видите, почти все сейчас создано в классах. Мы создаем атрибуты класса (которые похожи на глобальные переменные для класса), которые идентифицируют столбцы таблицы. Затем мы создаем то же __init__, что у нас было в исходном примере класса выше. Кроме того, мы подкласс Декларативность_base а не основные объект Отказ Если нам нужен объект таблицы, мы должны вызвать следующий магический метод Пользователь .__ Таблица __ ; И чтобы получить метаданные, нам нужно позвонить Base.Metadata Отказ Это охватывает различия, о которых мы заботимся о. Теперь мы можем посмотреть, как добавить данные в нашу базу данных.

Класс сейчас в сессии

Красота использования реляционного метода объекта для взаимодействия с нашей базой данных может быть показана в нескольких фрагментах быстрого кода. Давайте посмотрим, как мы можем создать ряд:

mike_user = User("mike", "Mike Driscoll", "password")
print "User name: %s, fullname: %s, password: %s" % (mike_user.name,
                                                     mike_user.fullname,
                                                     mike_user.password)

Как видите, мы можем создавать пользователей с классом пользователя. Мы можем использовать точечную обозначение для доступа к атрибутам, как мы бы в любом другом классе Python. Мы можем даже использовать их для обновления строк. Например, если нам нужно изменить объект пользователя выше, мы сделаем следующее:

# this is how you would change the name field
mike_user.fullname = "Mike Dryskull"

Обратите внимание, что ничто из этого не добавит строку в базу данных автоматически, как эти методы вставки, на которых мы смотрели в нашей первой статье. Вместо этого нам нужен объект сеанса для этого. Давайте пройдемся через некоторые основы использования сеанса:

from sqlalchemy.orm import sessionmaker

Session = sessionmaker(bind=engine)
session = Session()

mike_user = User("mike", "Mike Driscoll", "password")
session.add(mike_user)

Мы приостановимся здесь, чтобы объяснить, что происходит. Сначала нам нужно импортировать SessionMaker от sqlalchemy.orm И связывайте его с двигателем (технически, вы можете создать сеанс без привязки, но чтобы сделать что-нибудь полезное, вам нужно будет связать его в конце концов). Далее мы создаем экземпляр сеанса. Затем мы создали объект пользователя и добавьте его на сеанс. На данный момент код SQL не был запущен, и транзакция только в ожидании. Чтобы сохранить эту строку, нам нужно позвонить session.commit () или запустить запрос.

Если вам нужно добавить несколько пользователей, вы делаете это:

session.add_all([
     User('Mary', 'Mary Wonka', 'foobar'),
     User('Sue', 'Sue Lawhead', 'xxg527'),
     User('Fay', 'Fay Ray', 'blah')])

Если вы произошли, чтобы изменить один из атрибутов пользователя после совершения его в базу данных, вы можете использовать Session.dirty Чтобы проверить, какой из них был изменен. Если вам просто нужно знать, какие строки в ожидании, звоните Session.new Отказ Наконец, мы можем использовать Session.Rollback () откат транзакции.

Теперь давайте посмотрим на некоторые образец запросов:

# do a Select all
all_users = session.query(User).all()

# Select just one user by the name of "mike"
our_user = session.query(User).filter_by(name='mike').first()
print our_user

# select users that match "Mary" or "Fay"
users = session.query(User).filter(User.name.in_(['Mary', 'Fay'])).all()
print users

# select all and print out all the results sorted by id
for instance in session.query(User).order_by(User.id): 
    print instance.name, instance.fullname

Нам не нужно проходить каждый из них, поскольку у всех нас есть объяснения в комментариях. Вместо этого мы перейдем к теме присоединения.

Присоединиться к веселью

Есть присоединения, используя Синтаксис выражения SQL Что я не буду покрывать здесь. Скорее, мы будем использовать реляционную методологию объекта. Если вы оглядываетесь в любой из начинающих примеров для создания таблиц, вы заметите, что мы уже настроили соединение с Иностранник объект. Декларативный формат выглядел так:

user_id = Column(Integer, ForeignKey('users.id'))

# creates a bidirectional relationship
# from Address to User it's Many-to-One
# from User to Address it's One-to-Many
user = relation(User, backref=backref('addresses', order_by=id))

Посмотрим, как это работает, создавая новый пользователь:

prof = User("Prof", "Prof. Xavier", "fudge")
prof.addresses

Из-за Иностранник и Backref Команда, Пользователь Объект имеет адреса атрибут. Если вы запустите этот код, вы увидите, что он пуст. Давайте добавим некоторые адреса! (Примечание. Обязательно добавьте пользователя PROF на сеанс: Session.add (проф))))

prof.addresses = [Address(email_address='profx@dc.com'), 
                        Address(email_address='xavier@yahoo.com')]

Увидеть, как было легко? Еще легко получить информацию обратно. Например, если вы хотите получить доступ только к первому адресу, вы бы просто позвонили prof.addresses [0] Отказ Теперь скажем, что вам нужно изменить один из адресов (I.e. сделать обновление). Это так просто, как пирог:

# change the first address
prof.addresses[0].email_address = "profx@marvel.com"

Теперь давайте перейдем к выполнению запросов на присоединениях:

for u, a in session.query(User, Address).filter(User.id==Address.user_id).filter(Address.email_address=='xavier@yahoo.com').all():
    print u, a

Это один длинный запрос! Я нахожу тех, кто трудно следовать за собой, поэтому я обычно делаю следующее, чтобы облегчить мою мозгу:

sql = session.query(User, Address)
sql = sql.filter(User.id==Address.user_id)
sql = sql.filter(Address.email_address=='xavier@yahoo.com')

for u, a in sql.all():
    print u, a

Теперь, для тех из вас, что любят одноинал, в первом примере нет ничего плохого. Он будет производить точно такие же результаты. Я просто случился, чтобы упростить более длинную версию для отладки. Наконец, мы также можем использовать реальное соединение:

from sqlalchemy.orm import join
session.query(User).select_from(join(User, Address)).filter(Address.email_address=='xavier@yahoo.com').all()

Это также делает то же самое, что и предыдущие два примера, но более четко. Для получения дополнительной информации о присоединениях с помощью реляционного синтаксиса объекта я рекомендую Официальная документация Отказ

Обертывание

На данный момент вы должны быть в состоянии создать вашу базу данных с таблицами, заполнять таблицы с данными, а также выбирать, обновлять и совершать транзакции в вашу базу данных с помощью SQLALCHEMY. Я надеюсь, что вы нашли этот учебник полезным в понимании этой удивительной технологии.

Примечание. Этот учебник был протестирован на Windows с Python 2.5 и SQLALCHEMY 0.5.8.

Дальнейшее чтение