SlideShare una empresa de Scribd logo
1 de 39
Descargar para leer sin conexión
SQLAlchemy
доступ к реляционным данным
        в стиле Python


       Юревич Юрий, http://pyobject.ru

     Семинар Учебного центра Люксофт,
             16 сентября 2008
«SQLAlchemy — это
Python SQL тулкит и ORM,
 которые предоставляют
      разработчику
всю мощь и гибкость SQL»
                http://sqlalchemy.org


                                        2
Active Record (Django ORM, Storm)




                                3
Data Mapper (SQLAlchemy)




                           4
Архитектура SQLAlchemy




                         5
Про что будет




                6
Про что (почти) не будет




                           7
Управление схемой данных




                           8
Схема == метаданные




                      9
Создание таблиц: SQL
CREATE TABLE users (
     id INTEGER NOT NULL,
     name VARCHAR(255),
     PRIMARY KEY (id)
  );
CREATE TABLE creds (
     id INTEGER NOT NULL,
     user_id INTEGER,
     login VARCHAR(20),
     passwd VARCHAR(40),
     PRIMARY KEY (id),
     FOREIGN KEY(user_id)
      REFERENCES users (id)
  );



                                10
Создание таблиц: SQLAlchemy
meta = MetaData()
users = Table('users', meta,
    Column('id', Integer, primary_key=True),
    Column('name', Unicode(255)),
  )
creds = Table('creds', meta,
    Column('id', Integer, primary_key=True),
    Column('user_id', Integer, ForeignKey('users.id')),
    Column('login', String(20)),
    Column('passwd', String(40)),
  )




                                                          11
MetaData: что умеет
    Создавать/удалять:
●



        Всё сразу:
    –
            meta.create_all() / meta.drop_all()
        По отдельности:
    –
            users.create() / users.drop()
    Рефлексия:
●



        Потаблично:
    –
          users = Table('users', meta, autoload=True)
        Всё сразу:
    –
          meta.reflect()
    Интроспекция:
●


        meta.tables
    –
                                                        12
MetaData: пример из жизни

# ... описание схемы

def get_indexes():
    return [
        Index('ix_users_id', users.c.id, unique=True),
        Index('ix_creds_id', creds.c.id, unique=True),
        Index('ix_creds_user_id', creds.c.user_id),
    ]

def load():
    # ... загрузка данных
    pass

def postload():
    for ix in get_indexes():
        ix.create()
                                                         13
Язык SQL-выражений




                     14
Для любителей трехбуквенных
            сокращений
    DML (Data Managament Language):
●


        insert/update/delete
    –

    DQL (Data Query Language):
●


        select
    –




                                      15
Insert
    Данные указываются при создании
●

     ins = users.insert(values={'name': u'Jack'})
     ins.execute()

    Данные указываются при выполнении
●

     ins = users.insert()
     ins.execute(name=u'Jack')

    Несколько записей сразу
●

     ins = users.insert()
     ins.execute([{'name': u'Jack'}, {'name': u'Ed'}])

    Явно указывая соединение
●

     engine = create_engine('sqlite:///')
     ins = insert(users)
     engine.connect().execute(ins, {'name': u'Jack'})

                                                         16
Delete
    Условие — SQLAlchemy SQL expression
●

      del_ = users.delete(users.c.name==u'Jack')
      del_.execute()

    Условие — строка с SQL
●

      del_ = users.delete('users.name=:user')
      del_.params({'user': u'Jack'}).execute()




                                                   17
Select
SELECT *
FROM users


q = users.select()


SELECT users.id, users.name
FROM users


                              18
Select
SELECT id
FROM users
WHERE name='Jack'

q = users.select([users.c.id],
             users.c.name==u'Jack')

SELECT users.id
FROM users
WHERE users.name=:name

                                      19
Select
SELECT *
FROM users
JOIN creds ON
creds.user_id=users.id

q = users.join(creds).select()

SELECT users.id, users.name,
       creds.id, creds.user_id,
       creds.login, creds.passwd
JOIN creds ON
users.id=creds.user_id             20
Почему SA SQL Expr?
    Потому что Python круче SQL
●




                                  21
Почему SA SQL Expr?
    Потому что Python круче SQL
●


    Генерация SQL на лету:
●


        q = select([users, creds.c.login],
    –
                   from_obj=users.join(creds),
                   whereclause=users.c.name==u'Jack')
        q = users.select()
    –
        q = q.where(users.c.name==u'Jack')
        q = q.column(creds.c.login)
        q.append_from(join(users, creds))
        SELECT users.id, users.name, creds.login
    –
        FROM users
        JOIN creds ON creds.user_id = users.id
        WHERE users.name = 'Jack'

                                                        22
Object Relational Mapper (ORM)




                                 23
Data Mapper, снова




                     24
Рабочий пример:
 схема данных




                  25
Рабочий пример:
                    таблицы в SQL
CREATE TABLE users (              CREATE TABLE messages (
           id INTEGER NOT NULL,              id INTEGER NOT NULL,
           name VARCHAR(255),                subject VARCHAR(255),
           PRIMARY KEY (id)                  body TEXT,
   );                                        author_id INTEGER,
                                             PRIMARY KEY (id),
CREATE TABLE creds (                         FOREIGN KEY(author_id)
           id INTEGER NOT NULL,              REFERENCES users (id)
           user_id INTEGER,          );
           login VARCHAR(20),
           passwd VARCHAR(20),   CREATE TABLE message_recipients (
           PRIMARY KEY (id),                message_id INTEGER NOT NULL,
           FOREIGN KEY(user_id)             recipient_id INTEGER NOT NULL,
           REFERENCES users (id)            PRIMARY KEY (
                                                message_id, recipient_id),
);                                          FOREIGN KEY(message_id)
                                            REFERENCES messages (id),
                                            FOREIGN KEY(recipient_id)
                                            REFERENCES users (id)
                                    );


                                                                         26
Рабочий пример:
                   Данные
users = {
    u'Jack': ['jack', 'jack-rabbit'],
    u'Edvard': ['ed'],
    u'Mary': ['mary'],
}

messages = (
    {   'author': u'Jack', 'recipients': [u'Edvard', u'Mary'],
        'title': u'The first', 'body': u'Ha-ha, I'm the first!,
    },
    {   'author': u'Edvard', 'recipients': [u'Jack', u'Mary'],
        'title': u'Hey all', 'body': u'Hi, I'm here',
    },
    {
        'author': u'Edvard', 'recipients': [u'Mary'],
        'title': u'The silence', 'body': u'Why are you ignoring me?',
    },
    {
        'author': u'Mary', 'recipients': [u'Jack'],
        'title': u'Hi', 'body': u'Hi, Jack, how are you?',
    },
                                                                      27
)
Рабочий пример:
              таблицы в SA SQL Expr
users = Table('users', meta,
   Column('id', Integer, primary_key=True),
   Column('name', Unicode(255)),
   )

creds = Table('creds', meta,
   Column('id', Integer, primary_key=True),
   Column('user_id', Integer, ForeignKey('users.id')),
   Column('login', String(20)),
   Column('passwd', String(20)),
   )

messages = Table('messages', meta,
   Column('id', Integer, primary_key=True),
   Column('subject', Unicode(255)),
   Column('body', Text),
   Column('author_id', Integer, ForeignKey('users.id')),
   )

message_recipients = Table('message_recipients', meta,
   Column('message_id', Integer, ForeignKey('messages.id'), primary_key=True),
   Column('recipient_id', Integer, ForeignKey('users.id'), primary_key=True),
   )
                                                                           28
Рабочий пример:
                     Mappings
Session = scoped_session(sessionmaker(autoflush=False))

class Base(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

class User(Base):
    pass
class Cred(Base):
    pass
class Message(Base):
    pass

Session.mapper(User, users)                                 # (1)

Session.mapper(Cred, creds, properties={                    # (2)
    'user': relation(User, backref='credentials'),})

Session.mapper(Message, messages, properties={              # (3)
    'recipients': relation(User, backref='inbox',
                           secondary=message_recipients),
                                                                    29
    'author': relation(User, backref='outbox'),})
Рабочий пример:
                  готовность №1
[ 1]>>> import schema as sch
[ 2]>>> import mappings as m

[   3]>>>   engine = create_engine('sqlite:///example.sqlite')
[   4]>>>   sch.meta.bind = engine
[   5]>>>   sch.meta.create_all()
[   6]>>>   m.Session.bind = engine

[ 7]>>> u1 = m.User.query.get(1)
[ 8]>>> u1.id
<<< 1
[ 9]>>> u1.name
<<< u'Jack'
[10]>>> u1.credentials
<<< [<Cred: jack>, <Cred: jack-rabbit>]
[11]>>> u1.outbox
<<< [<Message: from Jack to Edvard, Mary (subj: The first)>]
                                                             30
Рабочий пример:
               выборки
[1]>>> q = m.User.query.filter(User.id>1)
[2]>>> print str(q)
SELECT users.id AS users_id, users.name AS users_name
FROM users
WHERE users.id > ?

[3]>>> q = q.filter(m.User.name!=None)
[4]>>> print str(q)
SELECT users.id AS users_id, users.name AS users_name
FROM users
WHERE users.id > ? AND users.name IS NOT NULL

[5]>>> list(q)
<<< [<User u'Edvard'>, <User u'Mary'>]

[6]>>> q.first()
<<< <User u'Edvard'>
                                                        31
Рабочий пример:
      выборки (продолжение)
[1]>>> rabbit = m.Cred.query.
           filter_by(login='jack-rabbit').one()

[2]>>> rabbit_user = m.User.query.
           filter(User.credentials.contains(rabbit)).
           one()


[3]>>> rabbit_messages = m.Message.query.
           filter(or_(
               Message.author==rabbit_user,
               Message.recipients.contains(rabbit_user)
       ))
[4]>>> list(rabbit_messages)
<<<
[<Message: from Jack to Edvard, Mary (subj: The first)>,
 <Message: from Edvard to Jack, Mary (subj: Hey all)>,
 <Message: from Mary to Jack (subj: Hi)>]              32
Рабочий пример:
          выборки (хардкор)
# Выбрать пользователей, у которых
# в исходящих больше одного сообщения
[1]>>> sess = m.Session()
[2]>>> q = sess.query(m.User, func.count('*')).
               join(m.Message).group_by(m.User).
               having(func.count('*')>1)
[3]>>> list(q)
<<< [(<User u'Edvard'>, 2)]

# Выбрать пользователей, у которых
# во входящих больше одного сообщения
[4]>>> sess = m.Session()
[5]>>> q = sess.query(m.User, func.count('*')).
         join(sch.message_recipients).group_by(m.User).
         having(func.count('*')>1)
[6]>>> list(q)
<<< [(<User u'Jack'>, 2), (<User u'Mary'>, 3)]
                                                      33
Рабочий пример:
                 сессия, unit of work
[   1]>>>   engine = create_engine('sqlite:///example.sqlite', echo=True)
[   2]>>>   sch.meta.bind = engine
[   3]>>>   m.Session.bind = engine
[   4]>>>   sess = m.Session()
[   5]>>>   jack = m.User.query.filter_by(name=u'Jack').one()
2008-09-14 14:19:11,504 INFO sqlalchemy.engine.base.Engine.0x...ca2c SELECT...
[ 6]>>> ed = m.User.query.filter_by(name=u'Edvard').one()
2008-09-14 14:20:22,731 INFO sqlalchemy.engine.base.Engine.0x...ca2c SELECT...
[ 7]>>> jack.name = u'Jack Daniels'
[ 8]>>> sess.dirty
<<< IdentitySet([<User u'Jack Daniels'>])
[ 9]>>> ed.name = u'Edvard Noringthon'
[10]>>> sess.dirty
<<< IdentitySet([<User u'Edvard Noringthon'>, <User u'Jack Daniels'>])
[11]>>> sess.flush()
2008-09-14 14:21:00,535 INFO sqlalchemy.engine.base.Engine.0x...ca2c
UPDATE users SET name=? WHERE users.id = ?
2008-09-14 14:21:00,535 INFO sqlalchemy.engine.base.Engine.0x...ca2c
['Jack Daniels', 1]
2008-09-14 14:21:00,604 INFO sqlalchemy.engine.base.Engine.0x...ca2c
UPDATE users SET name=? WHERE users.id = ?
2008-09-14 14:21:00,604 INFO sqlalchemy.engine.base.Engine.0x...ca2c
['Edvard Noringthon', 2]
                                                                                 34
users = Table(
    'users', meta, ...)

class User:
    pass

mapper(users, User)




 «user» 5 раз, скучно?
                          35
Elixir:
ActiveRecord поверх SQLAlchemy
    Elixir (http://elixir.ematia.de):
●


        Декларативное описание в стиле Django
    –

        События:
    –

             До (update, insert, delete)
         ●


             После (update, insert, delete)
         ●



        Плагины:
    –

             acts_as_versioned (автоматическое хранение истории)
         ●


             acts_as_encrypted (шифрование колонок)
         ●


             associable (аналог Django generic relations)
         ●


             ...
         ●



                                                               36
Еще вкусности SQLAlchemy
    «Хитрые» атрибуты:
●


          Отложенная/непосредственная подгрузка
     –

          SQL-выражение как атрибут
     –

    Партицирование:
●


          Вертикальное (часть таблиц в одной БД, часть в другой)
     –

          Горизонтальное (шардинг, содержимое одной таблицы
     –
                               «раскидано» по таблицам/БД)

    Нетривиальные маппинги:
●


          Несколько маппингов к одному классу
     –

          Маппинг классов к SQL-запросам
     –

    ...
●                                                                  37
Диагноз:
                нужна ли вам SA
    Используете другой           Используете DB
●                            ●

    ORM и счастливы?             API2 и «чистый»
                                 SQL?
        Нет, в SQLAlchemy
    –
        «много буков», нет           Да, SQLAlchemy
                                 –
        смысла                       даст вам это и много
                                     что еще




                                                        38
Вопросы?

 ... не успели задать? - шлите почтой: the.pythy@gmail.com



                                                       39

Más contenido relacionado

La actualidad más candente

Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Colin O'Dell
 
Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死Kiwamu Okabe
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented ArchitectureLuiz Messias
 
Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsFederico Tomassetti
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionIban Martinez
 
Implementation Specifications
Implementation SpecificationsImplementation Specifications
Implementation SpecificationsUnmon Mukherjee
 
Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumnameEmanuele Quinto
 
DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009Dirkjan Bussink
 
DOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript FrameworkDOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript FrameworkMatthew McCullough
 
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013Mosky Liu
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperGiordano Scalzo
 
MoSQL: More than SQL, but less than ORM
MoSQL: More than SQL, but less than ORMMoSQL: More than SQL, but less than ORM
MoSQL: More than SQL, but less than ORMMosky Liu
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoMohamed Mosaad
 
Final tagless and cats mtl
Final tagless and cats mtl Final tagless and cats mtl
Final tagless and cats mtl Alexander Zaidel
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Colin O'Dell
 
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Colin O'Dell
 

La actualidad más candente (20)

Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016
 
Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死
Play, Slick, play2-authの間で討死
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented Architecture
 
Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language Relations
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
Implementation Specifications
Implementation SpecificationsImplementation Specifications
Implementation Specifications
 
Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumname
 
DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009
 
DOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript FrameworkDOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript Framework
 
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
Daily notes
Daily notesDaily notes
Daily notes
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapper
 
MoSQL: More than SQL, but less than ORM
MoSQL: More than SQL, but less than ORMMoSQL: More than SQL, but less than ORM
MoSQL: More than SQL, but less than ORM
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
 
jQuery introduction
jQuery introductionjQuery introduction
jQuery introduction
 
Final tagless and cats mtl
Final tagless and cats mtl Final tagless and cats mtl
Final tagless and cats mtl
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016
 
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
 
Sk.php
Sk.phpSk.php
Sk.php
 

Destacado

What is NetFlow?
What is NetFlow?What is NetFlow?
What is NetFlow?NetHound
 
DPI Vas Experts Linkmeup
DPI Vas Experts LinkmeupDPI Vas Experts Linkmeup
DPI Vas Experts LinkmeupAlexander Fatin
 
Monitoring pg with_graphite_grafana
Monitoring pg with_graphite_grafanaMonitoring pg with_graphite_grafana
Monitoring pg with_graphite_grafanaJan Wieck
 
Will iPython replace bash?
Will iPython replace bash?Will iPython replace bash?
Will iPython replace bash?Roberto Polli
 
Scalable Monitoring & Alerting
Scalable Monitoring & AlertingScalable Monitoring & Alerting
Scalable Monitoring & AlertingFranklin Angulo
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In PythonMarwan Osman
 
Introducing wizzy - a CLI tool for Grafana
Introducing wizzy - a CLI tool for GrafanaIntroducing wizzy - a CLI tool for Grafana
Introducing wizzy - a CLI tool for GrafanaUTKARSH BHATNAGAR
 
Мониторинг. Опять, rootconf 2016
Мониторинг. Опять, rootconf 2016Мониторинг. Опять, rootconf 2016
Мониторинг. Опять, rootconf 2016Vsevolod Polyakov
 
Torkel Ödegaard (Creator of Grafana) - Grafana at #DOXLON
Torkel Ödegaard (Creator of Grafana) - Grafana at #DOXLONTorkel Ödegaard (Creator of Grafana) - Grafana at #DOXLON
Torkel Ödegaard (Creator of Grafana) - Grafana at #DOXLONOutlyer
 
Python for Linux System Administration
Python for Linux System AdministrationPython for Linux System Administration
Python for Linux System Administrationvceder
 
PHP to Python with No Regrets
PHP to Python with No RegretsPHP to Python with No Regrets
PHP to Python with No RegretsAlex Ezell
 
Real programmers use programming languages (Not shell scripts)
Real programmers use programming languages (Not shell scripts)Real programmers use programming languages (Not shell scripts)
Real programmers use programming languages (Not shell scripts)thedandan
 
ZFS Tutorial USENIX LISA09 Conference
ZFS Tutorial USENIX LISA09 ConferenceZFS Tutorial USENIX LISA09 Conference
ZFS Tutorial USENIX LISA09 ConferenceRichard Elling
 
MPLS (Multi-Protocol Label Switching)
MPLS  (Multi-Protocol Label Switching)MPLS  (Multi-Protocol Label Switching)
MPLS (Multi-Protocol Label Switching)NetProtocol Xpert
 

Destacado (20)

What is NetFlow?
What is NetFlow?What is NetFlow?
What is NetFlow?
 
Graphite
GraphiteGraphite
Graphite
 
Go with the flow
Go with the flowGo with the flow
Go with the flow
 
DPI Vas Experts Linkmeup
DPI Vas Experts LinkmeupDPI Vas Experts Linkmeup
DPI Vas Experts Linkmeup
 
Monitoring pg with_graphite_grafana
Monitoring pg with_graphite_grafanaMonitoring pg with_graphite_grafana
Monitoring pg with_graphite_grafana
 
Will iPython replace bash?
Will iPython replace bash?Will iPython replace bash?
Will iPython replace bash?
 
MPLS-TE Fault Tolerance
MPLS-TE Fault ToleranceMPLS-TE Fault Tolerance
MPLS-TE Fault Tolerance
 
Scalable Monitoring & Alerting
Scalable Monitoring & AlertingScalable Monitoring & Alerting
Scalable Monitoring & Alerting
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In Python
 
DDoS-bdNOG
DDoS-bdNOGDDoS-bdNOG
DDoS-bdNOG
 
Introducing wizzy - a CLI tool for Grafana
Introducing wizzy - a CLI tool for GrafanaIntroducing wizzy - a CLI tool for Grafana
Introducing wizzy - a CLI tool for Grafana
 
Мониторинг. Опять, rootconf 2016
Мониторинг. Опять, rootconf 2016Мониторинг. Опять, rootconf 2016
Мониторинг. Опять, rootconf 2016
 
Torkel Ödegaard (Creator of Grafana) - Grafana at #DOXLON
Torkel Ödegaard (Creator of Grafana) - Grafana at #DOXLONTorkel Ödegaard (Creator of Grafana) - Grafana at #DOXLON
Torkel Ödegaard (Creator of Grafana) - Grafana at #DOXLON
 
Hacking Cisco
Hacking CiscoHacking Cisco
Hacking Cisco
 
Python for Linux System Administration
Python for Linux System AdministrationPython for Linux System Administration
Python for Linux System Administration
 
Metrics: where and how
Metrics: where and howMetrics: where and how
Metrics: where and how
 
PHP to Python with No Regrets
PHP to Python with No RegretsPHP to Python with No Regrets
PHP to Python with No Regrets
 
Real programmers use programming languages (Not shell scripts)
Real programmers use programming languages (Not shell scripts)Real programmers use programming languages (Not shell scripts)
Real programmers use programming languages (Not shell scripts)
 
ZFS Tutorial USENIX LISA09 Conference
ZFS Tutorial USENIX LISA09 ConferenceZFS Tutorial USENIX LISA09 Conference
ZFS Tutorial USENIX LISA09 Conference
 
MPLS (Multi-Protocol Label Switching)
MPLS  (Multi-Protocol Label Switching)MPLS  (Multi-Protocol Label Switching)
MPLS (Multi-Protocol Label Switching)
 

Similar a SQLAlchemy Seminar

Achilles presentation
Achilles presentationAchilles presentation
Achilles presentationDuyhai Doan
 
Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)Joao Lucas Santana
 
Montreal Sql saturday: moving data from no sql db to azure data lake
Montreal Sql saturday: moving data from no sql db to azure data lakeMontreal Sql saturday: moving data from no sql db to azure data lake
Montreal Sql saturday: moving data from no sql db to azure data lakeDiponkar Paul
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019corehard_by
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Rabble .
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Rabble .
 
Uma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de Dados
Uma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de DadosUma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de Dados
Uma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de DadosCarlos Eduardo Pantoja
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsEleanor McHugh
 
Miniproject on Employee Management using Perl/Database.
Miniproject on Employee Management using Perl/Database.Miniproject on Employee Management using Perl/Database.
Miniproject on Employee Management using Perl/Database.Sanchit Raut
 
Работа с реляционными базами данных в C++
Работа с реляционными базами данных в C++Работа с реляционными базами данных в C++
Работа с реляционными базами данных в C++corehard_by
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In RailsLouie Zhao
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Will Button
 
Relaxing With CouchDB
Relaxing With CouchDBRelaxing With CouchDB
Relaxing With CouchDBleinweber
 
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...ActsAsCon
 
How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6Maxime Beugnet
 
Di web tech mail (no subject)
Di web tech mail   (no subject)Di web tech mail   (no subject)
Di web tech mail (no subject)shubhamvcs
 

Similar a SQLAlchemy Seminar (20)

Achilles presentation
Achilles presentationAchilles presentation
Achilles presentation
 
Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)
 
Montreal Sql saturday: moving data from no sql db to azure data lake
Montreal Sql saturday: moving data from no sql db to azure data lakeMontreal Sql saturday: moving data from no sql db to azure data lake
Montreal Sql saturday: moving data from no sql db to azure data lake
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
 
Django - sql alchemy - jquery
Django - sql alchemy - jqueryDjango - sql alchemy - jquery
Django - sql alchemy - jquery
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
 
Uma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de Dados
Uma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de DadosUma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de Dados
Uma Abordagem Orientada a Modelos para Modelagem Conceitual de Banco de Dados
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
greenDAO
greenDAOgreenDAO
greenDAO
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
 
Miniproject on Employee Management using Perl/Database.
Miniproject on Employee Management using Perl/Database.Miniproject on Employee Management using Perl/Database.
Miniproject on Employee Management using Perl/Database.
 
Работа с реляционными базами данных в C++
Работа с реляционными базами данных в C++Работа с реляционными базами данных в C++
Работа с реляционными базами данных в C++
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In Rails
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07
 
Relaxing With CouchDB
Relaxing With CouchDBRelaxing With CouchDB
Relaxing With CouchDB
 
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
 
How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6
 
Di web tech mail (no subject)
Di web tech mail   (no subject)Di web tech mail   (no subject)
Di web tech mail (no subject)
 

Más de Yury Yurevich

ekb.py: KISS REST API
ekb.py: KISS REST APIekb.py: KISS REST API
ekb.py: KISS REST APIYury Yurevich
 
ekb.py: Mini Zen of Python
ekb.py: Mini Zen of Pythonekb.py: Mini Zen of Python
ekb.py: Mini Zen of PythonYury Yurevich
 
PyCon UA 2011: Test Infected
PyCon UA 2011: Test InfectedPyCon UA 2011: Test Infected
PyCon UA 2011: Test InfectedYury Yurevich
 
Александр Гладыш — Visual editor for business logic in Lua and JS
Александр Гладыш — Visual editor for business logic in Lua and JSАлександр Гладыш — Visual editor for business logic in Lua and JS
Александр Гладыш — Visual editor for business logic in Lua and JSYury Yurevich
 
Лев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про ErlangЛев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про ErlangYury Yurevich
 
Ильшад Хабибуллин — BlueBream
Ильшад Хабибуллин — BlueBreamИльшад Хабибуллин — BlueBream
Ильшад Хабибуллин — BlueBreamYury Yurevich
 
Иван Иноземцев — Fantom
Иван Иноземцев — FantomИван Иноземцев — Fantom
Иван Иноземцев — FantomYury Yurevich
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — LuaYury Yurevich
 
About (unit) testing
About (unit) testingAbout (unit) testing
About (unit) testingYury Yurevich
 
Almost Success Story: Unix to Linux migration
Almost Success Story: Unix to Linux migrationAlmost Success Story: Unix to Linux migration
Almost Success Story: Unix to Linux migrationYury Yurevich
 

Más de Yury Yurevich (12)

ekb.py: KISS REST API
ekb.py: KISS REST APIekb.py: KISS REST API
ekb.py: KISS REST API
 
ekb.py: Mini Zen of Python
ekb.py: Mini Zen of Pythonekb.py: Mini Zen of Python
ekb.py: Mini Zen of Python
 
PyCon UA 2011: Test Infected
PyCon UA 2011: Test InfectedPyCon UA 2011: Test Infected
PyCon UA 2011: Test Infected
 
Александр Гладыш — Visual editor for business logic in Lua and JS
Александр Гладыш — Visual editor for business logic in Lua and JSАлександр Гладыш — Visual editor for business logic in Lua and JS
Александр Гладыш — Visual editor for business logic in Lua and JS
 
Лев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про ErlangЛев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про Erlang
 
Ильшад Хабибуллин — BlueBream
Ильшад Хабибуллин — BlueBreamИльшад Хабибуллин — BlueBream
Ильшад Хабибуллин — BlueBream
 
Иван Иноземцев — Fantom
Иван Иноземцев — FantomИван Иноземцев — Fantom
Иван Иноземцев — Fantom
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — Lua
 
Decorators' recipes
Decorators' recipesDecorators' recipes
Decorators' recipes
 
About Python
About PythonAbout Python
About Python
 
About (unit) testing
About (unit) testingAbout (unit) testing
About (unit) testing
 
Almost Success Story: Unix to Linux migration
Almost Success Story: Unix to Linux migrationAlmost Success Story: Unix to Linux migration
Almost Success Story: Unix to Linux migration
 

Último

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 

Último (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

SQLAlchemy Seminar

  • 1. SQLAlchemy доступ к реляционным данным в стиле Python Юревич Юрий, http://pyobject.ru Семинар Учебного центра Люксофт, 16 сентября 2008
  • 2. «SQLAlchemy — это Python SQL тулкит и ORM, которые предоставляют разработчику всю мощь и гибкость SQL» http://sqlalchemy.org 2
  • 3. Active Record (Django ORM, Storm) 3
  • 7. Про что (почти) не будет 7
  • 10. Создание таблиц: SQL CREATE TABLE users ( id INTEGER NOT NULL, name VARCHAR(255), PRIMARY KEY (id) ); CREATE TABLE creds ( id INTEGER NOT NULL, user_id INTEGER, login VARCHAR(20), passwd VARCHAR(40), PRIMARY KEY (id), FOREIGN KEY(user_id) REFERENCES users (id) ); 10
  • 11. Создание таблиц: SQLAlchemy meta = MetaData() users = Table('users', meta, Column('id', Integer, primary_key=True), Column('name', Unicode(255)), ) creds = Table('creds', meta, Column('id', Integer, primary_key=True), Column('user_id', Integer, ForeignKey('users.id')), Column('login', String(20)), Column('passwd', String(40)), ) 11
  • 12. MetaData: что умеет Создавать/удалять: ● Всё сразу: – meta.create_all() / meta.drop_all() По отдельности: – users.create() / users.drop() Рефлексия: ● Потаблично: – users = Table('users', meta, autoload=True) Всё сразу: – meta.reflect() Интроспекция: ● meta.tables – 12
  • 13. MetaData: пример из жизни # ... описание схемы def get_indexes(): return [ Index('ix_users_id', users.c.id, unique=True), Index('ix_creds_id', creds.c.id, unique=True), Index('ix_creds_user_id', creds.c.user_id), ] def load(): # ... загрузка данных pass def postload(): for ix in get_indexes(): ix.create() 13
  • 15. Для любителей трехбуквенных сокращений DML (Data Managament Language): ● insert/update/delete – DQL (Data Query Language): ● select – 15
  • 16. Insert Данные указываются при создании ● ins = users.insert(values={'name': u'Jack'}) ins.execute() Данные указываются при выполнении ● ins = users.insert() ins.execute(name=u'Jack') Несколько записей сразу ● ins = users.insert() ins.execute([{'name': u'Jack'}, {'name': u'Ed'}]) Явно указывая соединение ● engine = create_engine('sqlite:///') ins = insert(users) engine.connect().execute(ins, {'name': u'Jack'}) 16
  • 17. Delete Условие — SQLAlchemy SQL expression ● del_ = users.delete(users.c.name==u'Jack') del_.execute() Условие — строка с SQL ● del_ = users.delete('users.name=:user') del_.params({'user': u'Jack'}).execute() 17
  • 18. Select SELECT * FROM users q = users.select() SELECT users.id, users.name FROM users 18
  • 19. Select SELECT id FROM users WHERE name='Jack' q = users.select([users.c.id], users.c.name==u'Jack') SELECT users.id FROM users WHERE users.name=:name 19
  • 20. Select SELECT * FROM users JOIN creds ON creds.user_id=users.id q = users.join(creds).select() SELECT users.id, users.name, creds.id, creds.user_id, creds.login, creds.passwd JOIN creds ON users.id=creds.user_id 20
  • 21. Почему SA SQL Expr? Потому что Python круче SQL ● 21
  • 22. Почему SA SQL Expr? Потому что Python круче SQL ● Генерация SQL на лету: ● q = select([users, creds.c.login], – from_obj=users.join(creds), whereclause=users.c.name==u'Jack') q = users.select() – q = q.where(users.c.name==u'Jack') q = q.column(creds.c.login) q.append_from(join(users, creds)) SELECT users.id, users.name, creds.login – FROM users JOIN creds ON creds.user_id = users.id WHERE users.name = 'Jack' 22
  • 26. Рабочий пример: таблицы в SQL CREATE TABLE users ( CREATE TABLE messages ( id INTEGER NOT NULL, id INTEGER NOT NULL, name VARCHAR(255), subject VARCHAR(255), PRIMARY KEY (id) body TEXT, ); author_id INTEGER, PRIMARY KEY (id), CREATE TABLE creds ( FOREIGN KEY(author_id) id INTEGER NOT NULL, REFERENCES users (id) user_id INTEGER, ); login VARCHAR(20), passwd VARCHAR(20), CREATE TABLE message_recipients ( PRIMARY KEY (id), message_id INTEGER NOT NULL, FOREIGN KEY(user_id) recipient_id INTEGER NOT NULL, REFERENCES users (id) PRIMARY KEY ( message_id, recipient_id), ); FOREIGN KEY(message_id) REFERENCES messages (id), FOREIGN KEY(recipient_id) REFERENCES users (id) ); 26
  • 27. Рабочий пример: Данные users = { u'Jack': ['jack', 'jack-rabbit'], u'Edvard': ['ed'], u'Mary': ['mary'], } messages = ( { 'author': u'Jack', 'recipients': [u'Edvard', u'Mary'], 'title': u'The first', 'body': u'Ha-ha, I'm the first!, }, { 'author': u'Edvard', 'recipients': [u'Jack', u'Mary'], 'title': u'Hey all', 'body': u'Hi, I'm here', }, { 'author': u'Edvard', 'recipients': [u'Mary'], 'title': u'The silence', 'body': u'Why are you ignoring me?', }, { 'author': u'Mary', 'recipients': [u'Jack'], 'title': u'Hi', 'body': u'Hi, Jack, how are you?', }, 27 )
  • 28. Рабочий пример: таблицы в SA SQL Expr users = Table('users', meta, Column('id', Integer, primary_key=True), Column('name', Unicode(255)), ) creds = Table('creds', meta, Column('id', Integer, primary_key=True), Column('user_id', Integer, ForeignKey('users.id')), Column('login', String(20)), Column('passwd', String(20)), ) messages = Table('messages', meta, Column('id', Integer, primary_key=True), Column('subject', Unicode(255)), Column('body', Text), Column('author_id', Integer, ForeignKey('users.id')), ) message_recipients = Table('message_recipients', meta, Column('message_id', Integer, ForeignKey('messages.id'), primary_key=True), Column('recipient_id', Integer, ForeignKey('users.id'), primary_key=True), ) 28
  • 29. Рабочий пример: Mappings Session = scoped_session(sessionmaker(autoflush=False)) class Base(object): def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) class User(Base): pass class Cred(Base): pass class Message(Base): pass Session.mapper(User, users) # (1) Session.mapper(Cred, creds, properties={ # (2) 'user': relation(User, backref='credentials'),}) Session.mapper(Message, messages, properties={ # (3) 'recipients': relation(User, backref='inbox', secondary=message_recipients), 29 'author': relation(User, backref='outbox'),})
  • 30. Рабочий пример: готовность №1 [ 1]>>> import schema as sch [ 2]>>> import mappings as m [ 3]>>> engine = create_engine('sqlite:///example.sqlite') [ 4]>>> sch.meta.bind = engine [ 5]>>> sch.meta.create_all() [ 6]>>> m.Session.bind = engine [ 7]>>> u1 = m.User.query.get(1) [ 8]>>> u1.id <<< 1 [ 9]>>> u1.name <<< u'Jack' [10]>>> u1.credentials <<< [<Cred: jack>, <Cred: jack-rabbit>] [11]>>> u1.outbox <<< [<Message: from Jack to Edvard, Mary (subj: The first)>] 30
  • 31. Рабочий пример: выборки [1]>>> q = m.User.query.filter(User.id>1) [2]>>> print str(q) SELECT users.id AS users_id, users.name AS users_name FROM users WHERE users.id > ? [3]>>> q = q.filter(m.User.name!=None) [4]>>> print str(q) SELECT users.id AS users_id, users.name AS users_name FROM users WHERE users.id > ? AND users.name IS NOT NULL [5]>>> list(q) <<< [<User u'Edvard'>, <User u'Mary'>] [6]>>> q.first() <<< <User u'Edvard'> 31
  • 32. Рабочий пример: выборки (продолжение) [1]>>> rabbit = m.Cred.query. filter_by(login='jack-rabbit').one() [2]>>> rabbit_user = m.User.query. filter(User.credentials.contains(rabbit)). one() [3]>>> rabbit_messages = m.Message.query. filter(or_( Message.author==rabbit_user, Message.recipients.contains(rabbit_user) )) [4]>>> list(rabbit_messages) <<< [<Message: from Jack to Edvard, Mary (subj: The first)>, <Message: from Edvard to Jack, Mary (subj: Hey all)>, <Message: from Mary to Jack (subj: Hi)>] 32
  • 33. Рабочий пример: выборки (хардкор) # Выбрать пользователей, у которых # в исходящих больше одного сообщения [1]>>> sess = m.Session() [2]>>> q = sess.query(m.User, func.count('*')). join(m.Message).group_by(m.User). having(func.count('*')>1) [3]>>> list(q) <<< [(<User u'Edvard'>, 2)] # Выбрать пользователей, у которых # во входящих больше одного сообщения [4]>>> sess = m.Session() [5]>>> q = sess.query(m.User, func.count('*')). join(sch.message_recipients).group_by(m.User). having(func.count('*')>1) [6]>>> list(q) <<< [(<User u'Jack'>, 2), (<User u'Mary'>, 3)] 33
  • 34. Рабочий пример: сессия, unit of work [ 1]>>> engine = create_engine('sqlite:///example.sqlite', echo=True) [ 2]>>> sch.meta.bind = engine [ 3]>>> m.Session.bind = engine [ 4]>>> sess = m.Session() [ 5]>>> jack = m.User.query.filter_by(name=u'Jack').one() 2008-09-14 14:19:11,504 INFO sqlalchemy.engine.base.Engine.0x...ca2c SELECT... [ 6]>>> ed = m.User.query.filter_by(name=u'Edvard').one() 2008-09-14 14:20:22,731 INFO sqlalchemy.engine.base.Engine.0x...ca2c SELECT... [ 7]>>> jack.name = u'Jack Daniels' [ 8]>>> sess.dirty <<< IdentitySet([<User u'Jack Daniels'>]) [ 9]>>> ed.name = u'Edvard Noringthon' [10]>>> sess.dirty <<< IdentitySet([<User u'Edvard Noringthon'>, <User u'Jack Daniels'>]) [11]>>> sess.flush() 2008-09-14 14:21:00,535 INFO sqlalchemy.engine.base.Engine.0x...ca2c UPDATE users SET name=? WHERE users.id = ? 2008-09-14 14:21:00,535 INFO sqlalchemy.engine.base.Engine.0x...ca2c ['Jack Daniels', 1] 2008-09-14 14:21:00,604 INFO sqlalchemy.engine.base.Engine.0x...ca2c UPDATE users SET name=? WHERE users.id = ? 2008-09-14 14:21:00,604 INFO sqlalchemy.engine.base.Engine.0x...ca2c ['Edvard Noringthon', 2] 34
  • 35. users = Table( 'users', meta, ...) class User: pass mapper(users, User) «user» 5 раз, скучно? 35
  • 36. Elixir: ActiveRecord поверх SQLAlchemy Elixir (http://elixir.ematia.de): ● Декларативное описание в стиле Django – События: – До (update, insert, delete) ● После (update, insert, delete) ● Плагины: – acts_as_versioned (автоматическое хранение истории) ● acts_as_encrypted (шифрование колонок) ● associable (аналог Django generic relations) ● ... ● 36
  • 37. Еще вкусности SQLAlchemy «Хитрые» атрибуты: ● Отложенная/непосредственная подгрузка – SQL-выражение как атрибут – Партицирование: ● Вертикальное (часть таблиц в одной БД, часть в другой) – Горизонтальное (шардинг, содержимое одной таблицы – «раскидано» по таблицам/БД) Нетривиальные маппинги: ● Несколько маппингов к одному классу – Маппинг классов к SQL-запросам – ... ● 37
  • 38. Диагноз: нужна ли вам SA Используете другой Используете DB ● ● ORM и счастливы? API2 и «чистый» SQL? Нет, в SQLAlchemy – «много буков», нет Да, SQLAlchemy – смысла даст вам это и много что еще 38
  • 39. Вопросы? ... не успели задать? - шлите почтой: the.pythy@gmail.com 39