associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

Diferenças para "DicasSqlalchemy"

Diferenças entre as versões de 8 e 9
Revisão 8e 2009-12-17 19:51:41
Tamanho: 1840
Comentário:
Revisão 9e 2009-12-17 20:13:25
Tamanho: 4843
Comentário:
Deleções são marcadas assim. Adições são marcadas assim.
Linha 1: Linha 1:
<<TableOfContents>>  <<TableOfContents>>
Linha 64: Linha 64:


== Usando o ORM e classes mapeadas ==

db.py
db.py
{{{#!python
from sqlalchemy import create_engine, Table, Column, MetaData
from sqlalchemy import Boolean, Integer, Unicode, String
from sqlalchemy.engine.url import URL
from sqlalchemy.orm import sessionmaker, mapper
import random
import string

### para conexao no sqlite:
_url = 'sqlite://'
### para conexao no firebird
# _url = URL('firebird', 'SYSDBA', 'masterkey', '192.168.1.11', '3052', 'bdband')
### para conexao no mysql
# _url = 'mysql://usuario:senha@servidor/banco'

# cria o engine e metadata
engine = create_engine(_url, echo=True)
metadata = MetaData(bind=engine)

#cria as tabelas
tb_usuarios = Table('usuarios', metadata,
                 Column('id', Integer, primary_key=True),
                 Column('nome', Unicode(20), nullable=False),
                 Column('senha', String(10), nullable=False),
                 Column('ativo', Boolean, nullable=False)
        )

#cria as classes
class Usuario(object):
    def __init__(self, nome, senha=None, ativo=False):
        if senha is None:
            # gera uma senha aleatoria
            senha = ''.join(random.choice(string.letters + string.digits)
                            for x in xrange(10))
        self.nome = nome
        self.senha = senha
        self.ativo = ativo

    # um metodo simples para demontrar que a classe pode ter quaisquer metodos
    def verifica_senha(self, senha_verificar):
        return self.senha == senha_verificar

# mapeia a classe -> tabela
mapper(Usuario, tb_usuarios)

#cria as tabelas no banco (caso nao existam)
metadata.create_all()

#cria o sessionmaker
Session = sessionmaker(bind=engine)
}}}

Usando:

{{{#!python
import db

#posso criar uma instancia da minha classe
u = db.Usuario(u'big_rid')
# alterar atributos
u.senha = '123456'

# na hora de usar pega uma sessao
s = db.Session()
s.add(u) # adiciona o objeto a sessao
s.add_all([ # para adicionar varios objetos mesmo tempo
        db.Usuario(nome=u'jack', ativo=True),
        db.Usuario(nome=u'jonh', senha='senha'),
    ])
s.commit()

# Posso alterar minha instancia, o sqlalchemy gera um UPDATE automaticamente
u.ativo = True
s.commit() # UPDATE usuarios SET ativo = 1 WHERE id = ?

s.close()
}}}


Consultando (queries)
{{{#!python
from contextlib import closing
import db

with closing(db.Session()) as s:
    # uma query retornara instancias da classe definida acima
    for usu in s.query(db.Usuario).filter(db.Usuario.ativo == True):
        print usu.nome, usu.id, usu.senha, usu.ativo
        # chamo um metodo customizado no objeto retornado:
        if usu.verifica_senha('123456'):
            # posso alterar o objeto, sqlalchemy gera UPDATE
            usu.senha = '321321'
            print 'senha alterada'
    s.commit()

# sessao fechada automaticamente, mesmo se der erro. (no caso de erro
# um ROLLBACK sera dado na transacao automaticamente)
}}}

Usando sqlalchemy

Usando somente a query expression language

db.py

   1 from sqlalchemy import create_engine, Table, Column, MetaData
   2 from sqlalchemy import Boolean, Integer, Unicode, String
   3 from sqlalchemy.engine.url import URL
   4 
   5 ### para conexao no sqlite:
   6 _url = 'sqlite://'
   7 ### para conexao no firebird
   8 # _url = URL('firebird', 'SYSDBA', 'masterkey', '192.168.1.11', '3052', 'bdband')
   9 ### para conexao no mysql
  10 # _url = 'mysql://usuario:senha@servidor/banco'
  11 
  12 # cria o engine e metadata
  13 engine = create_engine(_url)
  14 metadata = MetaData(bind=engine)
  15 
  16 #cria as tabelas
  17 tb_usuarios = Table('usuarios', metadata,
  18                  Column('id', Integer, primary_key=True),
  19                  Column('nome', Unicode(20), nullable=False),
  20                  Column('senha', String(10), nullable=False),
  21                  Column('ativo', Boolean, nullable=False)
  22         )
  23 
  24 #cria as tabelas no banco (caso nao existam)
  25 metadata.create_all()

Exemplo de uso do arquivo acima

   1 import db
   2 
   3 # na hora de usar pega uma conexao
   4 con = db.engine.connect()
   5 ins = db.tb_usuarios.insert()
   6 con.execute(ins, [
   7                 dict(nome=u'jack', senha='senha', ativo=True),
   8                 dict(nome=u'jonh', senha='ahnes', ativo=False), 
   9             ])
  10 con.close()

Um outro exemplo de uso, desta vez para consulta, e usando o contextlib.closing para fechar a conexão:

   1 import db
   2 from contextlib import closing
   3 
   4 with closing(db.engine.connect()) as con:
   5     sel_usuarios = db.tb_usuarios.select(db.tb_usuarios.c.ativo) 
   6     resultado = con.execute(sel_usuarios)
   7     for registro in resultado:
   8         print registro.nome, registro.id, registro.senha, registro.ativo
   9 # conexao fechada automaticamente, mesmo se der algum erro

Usando o ORM e classes mapeadas

db.py db.py

   1 from sqlalchemy import create_engine, Table, Column, MetaData
   2 from sqlalchemy import Boolean, Integer, Unicode, String
   3 from sqlalchemy.engine.url import URL
   4 from sqlalchemy.orm import sessionmaker, mapper
   5 import random
   6 import string
   7 
   8 ### para conexao no sqlite:
   9 _url = 'sqlite://'
  10 ### para conexao no firebird
  11 # _url = URL('firebird', 'SYSDBA', 'masterkey', '192.168.1.11', '3052', 'bdband')
  12 ### para conexao no mysql
  13 # _url = 'mysql://usuario:senha@servidor/banco'
  14 
  15 # cria o engine e metadata
  16 engine = create_engine(_url, echo=True)
  17 metadata = MetaData(bind=engine)
  18 
  19 #cria as tabelas
  20 tb_usuarios = Table('usuarios', metadata,
  21                  Column('id', Integer, primary_key=True),
  22                  Column('nome', Unicode(20), nullable=False),
  23                  Column('senha', String(10), nullable=False),
  24                  Column('ativo', Boolean, nullable=False)
  25         )
  26 
  27 #cria as classes
  28 class Usuario(object):
  29     def __init__(self, nome, senha=None, ativo=False):
  30         if senha is None:
  31             # gera uma senha aleatoria
  32             senha = ''.join(random.choice(string.letters + string.digits)
  33                             for x in xrange(10))
  34         self.nome = nome
  35         self.senha = senha
  36         self.ativo = ativo
  37 
  38     # um metodo simples para demontrar que a classe pode ter quaisquer metodos
  39     def verifica_senha(self, senha_verificar):
  40         return self.senha == senha_verificar
  41 
  42 # mapeia a classe -> tabela
  43 mapper(Usuario, tb_usuarios)
  44 
  45 #cria as tabelas no banco (caso nao existam)
  46 metadata.create_all()
  47 
  48 #cria o sessionmaker
  49 Session = sessionmaker(bind=engine)

Usando:

   1 import db
   2 
   3 #posso criar uma instancia da minha classe
   4 u = db.Usuario(u'big_rid')
   5 # alterar atributos
   6 u.senha = '123456'
   7 
   8 # na hora de usar pega uma sessao
   9 s = db.Session()
  10 s.add(u) # adiciona o objeto a sessao
  11 s.add_all([ # para adicionar varios objetos mesmo tempo
  12         db.Usuario(nome=u'jack', ativo=True),
  13         db.Usuario(nome=u'jonh', senha='senha'),
  14     ])
  15 s.commit()
  16 
  17 # Posso alterar minha instancia, o sqlalchemy gera um UPDATE automaticamente
  18 u.ativo = True
  19 s.commit() # UPDATE usuarios SET ativo = 1 WHERE id = ?
  20 
  21 s.close()

Consultando (queries)

   1 from contextlib import closing
   2 import db
   3 
   4 with closing(db.Session()) as s:
   5     # uma query retornara instancias da classe definida acima
   6     for usu in s.query(db.Usuario).filter(db.Usuario.ativo == True):
   7         print usu.nome, usu.id, usu.senha, usu.ativo
   8         # chamo um metodo customizado no objeto retornado:
   9         if usu.verifica_senha('123456'):
  10             # posso alterar o objeto, sqlalchemy gera UPDATE
  11             usu.senha = '321321'
  12             print 'senha alterada'
  13     s.commit()
  14 
  15 # sessao fechada automaticamente, mesmo se der erro. (no caso de erro
  16 # um ROLLBACK sera dado na transacao automaticamente)