Como fazer ORM Mapeamento Objeto Relacional em Python com SqlAlchemy parte I

Posted on jun 05, 2008 under Python | 4 Comentários

Introdução:

ORM (Object Relacional Mapper), Mapeamento objeto relacional serve para reduzir a impedância entre banco de dados relacional e programação orientada a objetos. O modelo relacional de banco de dados é muito confiável sendo largamente utilizado nos dias de hoje, sendo baseado em tabelas, linhas e colunas, já a programação orientada a objetos tem como elemento base um objeto que é definido por seus atributos e métodos.

Para desenvolver um software orientado a objetos, salvando o estado dos objetos em um banco de dados relacionais, pode ser feito manualmente através de SQL o que é complicado. Por isso usaremos o SQLAlchemy que fará esse mapeamento objeto relacional.

Este tutorial demonstra como utilizar o SQLalchemy versão 0.4.6, que é uma ferramenta SQL escrita em Python e um ORM(Object Relacional Mapper), fornecendo uma camada de abstração para unir os dois mundos, sendo possível desenvolver software sem usar SQL, para interagir com o banco de dados.

O SQLAchemy possui dialetos para se comunicar com os seguintes banco de dados: SQLite, Postgres, MySQL, Oracle, MS-SQL, Firebird, MaxDB, MS Access, Sybase and Informix; DB2.


Instalando:

Para instalar o SQLAlchemy iremos utilizar a ferramenta setuptools que pode ser baixada aqui, e instalada com o seguinte comando:

python ez_setup.py

Após instalado o setuptools agora iremos instalar o SQLAlchemy com o comando:

easy_install SQLAlchemy

Este comando irá conectar a internet, baixar a última versão e instalar na sua máquina.

Necessitamos também de um banco de dados. Para facilitar nossa vida iremos utilizar o sqlite3, um banco de dados simples de utilizar e instalar:

Instalando sqlite3 gentoo

emerge -av sqlite

Pode ser instalado também baixando o um binário pré compilado


wget http://www.sqlite.org/sqlite3-3.5.9.bin.gz
gunzip sqlite3-3.5.9.bin.gz
cp sqlite3-3.5.9.bin /usr/bin

Instalar o pysqlite3 para python conectar ao banco sqlite3

easy_install pysqlite

Definindo as Classes

Começaremos definindo as classes que serão mapeadas para o banco de dados. O nosso domínio será um sistema de venda online mas no momento iremos criar a classe Cliente, mapear ela no banco, logo após salvar ela no banco, e executar algumas pesquisas. Na segunda parte será criado um relacionamento um para muitos onde iremos criar a classe endereço, e na última parte iremos mapear a classe Forma de Pagamento que será a superclasse das classes Cartão de Credito, dinheiro e boleto.

Logo abaixo está o código completo utilizado, após o código explicaremos linha por linha:

from sqlalchemy import *
from sqlalchemy.orm import *

class Cliente(object):

	def __init__(self,nome,rg,cpf):
		self.nome = nome
		self.rg = rg
		self.cpf = cpf

	def __repr__(self):
		return "" % (self.nome,self.rg,self.cpf)	

db = create_engine('sqlite:///:memory:', echo=False)

metadata = MetaData()	

#Cria a tabela Cliente

ClienteTable = Table('cliente', metadata,
	Column('id', Integer, primary_key=True),
	Column('nome', String(40)),
	Column('rg', String(10)),
	Column('cpf', String(12))
)

metadata.create_all(db) 

#mapeando
mapper(Cliente,ClienteTable)

cliente1 = Cliente('Marlon','1012123302','12345678901')
cliente2 = Cliente('Paulo','3414423302','12345678901')
cliente3 = Cliente('Joao','8765123302','12345678901')
cliente4 = Cliente('Jose','3212123302','12345678901')
cliente5 = Cliente('Mauro','3456123302','12345678901')

#criando a sessao

Session = sessionmaker(bind=db, autoflush=True, transactional=True)

session = Session()

session.save(cliente1)
session.save(cliente2)
session.save(cliente3)
session.save(cliente4)
session.save(cliente5)

session.commit()

#consultando

query = session.query(Cliente)

print 'Lista todos e mostra o nome\n'
for cliente in session.query(Cliente):
	print cliente.nome

print '\nLIMIT e OFFSET\n'

for c in session.query(Cliente)[1:3]:
	print c

print '\nFiltrando por Nome\n'

for cliente in session.query(Cliente).filter_by(nome='Marlon'):
	print cliente

print '\n Usando like\n'

query = session.query(Cliente).filter(Cliente.nome.like('%Ma%'))
query.all()

Importando as bibliotecas

Na linhas 1 e 2 são importadas todas as classes da bibliotecas sqlalchemy e sqlalchemy.orm

Definindo a classe Cliente

A classe cliente é definida a partir da linha 4 até a linha 12, possuindo os seguintes atributos: nome, rg e cpf. O construtor da classe __init__(self, nome, rg, cpf) tem como parametros o nome, rg e cpf o metodo __repr__(self):, serve para mostrar uma string de representação da classe.

Conectando ao Banco

Nesse tutorial é utilizado o banco de dados sqlite in-memory, sendo útil testar o mapeamento. A conexão com o banco é realizada na linha 15. A variável echo serve para mostrar os comandos sql que serão executados no banco, caso não seja do seu interesse ver os comando SQL gerados ajuste a variável para False ex: echo=False.

Definindo e criando as tabelas

Devemos informar para o SqlAlchemy os tabelas que iremos utilizar a sintaxe é parecida com o comando CREATE TABLE do SQL, as definições da nossa primeira tabela é demonstrada a partir da linha 22 até a 27.

O objeto MetaData que faz a ligação entre o objeto em Python com o banco de dados, se perceber na linha 22, devemos passar o objeto metadata para criar a tabela cliente. E no próximo passo devemos informar ao objeto metadata que queremos criar a tabela dentro do banco, para isso o método create_all(db) deve ser chamado linha 29 passando o objeto de referencia para o banco de dados. Então antes de executar o comando SQL será verificado se a tabela já existe no banco ou não.


2008-06-03 14:51:21,192 INFO sqlalchemy.engine.base.Engine.0x..2c PRAGMA table_info("cliente")
2008-06-03 14:51:21,193 INFO sqlalchemy.engine.base.Engine.0x..2c {}
2008-06-03 14:51:21,195 INFO sqlalchemy.engine.base.Engine.0x..2c
CREATE TABLE cliente (
        id INTEGER NOT NULL,
        nome VARCHAR(40),
        rg VARCHAR(10),
        cpf VARCHAR(12),
        PRIMARY KEY (id)
)

2008-06-03 14:51:21,196 INFO sqlalchemy.engine.base.Engine.0x..2c {}
2008-06-03 14:51:21,197 INFO sqlalchemy.engine.base.Engine.0x..2c COMMIT

Agora a tabela no banco está criada com as colunas necessárias para a classe cliente, então devemos fazer o mapeamento objeto relacional.

Mapeando

Para realizar o mapeamento objeto relacional utilizamos a biblioteca sqlalchemy.orm esta possui o método mapper() o qual cria um mapeamento entre a tabela ClientTable e a classe Cliente mostrado na linha 31.

Agora vamos criar 5 clientes conforme mostrado da linha 33 a 37, note que devemos informar o nome, rg e cpf.
Executando em um terminal python

>>> cliente1
>>> str(cliente1.id)
'None'

De onde surgiu o atributo id pois na classe Cliente não temos esse atributo. Esse atributo foi inserido na nossa classe quando realizamos o mapeamento na linha 31 veja


>>>dir(Cliente)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_class_state', 'c', 'cpf', 'id', 'nome', 'rg']
>>>

Os atributos da classe Cliente foram modificados para realizar o mapeamento. O atributo id serve para mostrar o indice na tabela por enquanto esta nulo, mas no momento que chamarmos o método commit() na linha 50 ele será automaticamente atualizado.

Criando a sessão

Como já definimos a classe e a tabela podemos interagir com o banco, para existir a interação devemos criar o objeto Session, na linha 40 chamamos o construtor sessionmaker onde passamos como parâmetro o conexão com o banco bind = db, autoFlush=True e transactional=True informado que iremos utilizar transações.
E na linha 42 criamos o objeto session, agora já podemos salvar nossos clientes no banco, executar o session.commit() e ver o que acontece com o atributo id.

>>>cliente1.id
1

Então nosso cliente está salva no banco. Para ficar mais interessante vamos realizar uma pesquisas (queries).

Consultando

As consultas utilizam o método session.query(objeto) no nosso exemplo o objeto será a classe Cliente.

Na linha 59 até a 61 tem o exemplo de um laço “for” que mostra o nome de todos os clientes.

A linha 67 e 68 mostra um exemplo de como usar Limit e Offset

Já na linha 72 e 73 mostra como listar todos os cliente que tenha o nome Marlon.

E por fim a linha 77 e 78 mostra o uso de expressões regulares, listando todos os clientes que contenham as letras %Ma%.

Qualquer duvida deixe um comentário será um prazer esclarecer.

Download do código

4 Responses to “Como fazer ORM Mapeamento Objeto Relacional em Python com SqlAlchemy parte I”

  1. Como fazer ORM Mapeamento Objeto Relacional em Python com SqlAlchemy part1…

    Olá pessoal nesse post fiz um tutorial de como fazer programar orientado a objetos e utilizar um banco de dados relacional. Confira…

  2. domelhor.net disse:

    Tutorial sobre ORM em Pyton – petryx.blogrs.com.br…

  3. Ricardo disse:

    Muito bom o tutorial. Só faltou o velho problema das línguas latinas: a acentuação. Como resolver essa “engronha”?
    Grande abraço e sucesso.
    Ricardo

  4. Marlon Petry disse:

    Olá Ricardo

    Você pode tentar utilizar Column(‘nome’, Unicode(40)) e no cabeçalho do programa # -*- coding: latin-1 -*-

    Obrigado pela comentário.

Leave a Reply