2. DB-API
• Python Database API Specification;
• Módulos que integram Python a uma tecnologia de banco de dados devem
implementar esta especificação;
• Conceitos:
• Conexão: Canal de comunicação entre o SGBD e a aplicação;
• Cursor: Objeto responsável por enviar comandos ao banco de dados.
3. DB-API
• Operações sobre conexões:
• commit: persiste os dados de uma sessão no banco de dados;
• rollback: descarta os valores da sessão;
• Operações sobre cursores:
• execute: executa um comando no banco de dados;
• fetchall: retorna todos os valores produzidos pelo comando executado;
• fetchone: retorna apenas um valor;
• fechsome: retorna no máximo o número especificado de valores.
4. SQLITE
• Já vem integrado com o Python a partir da versão 2.5;
• Acessível através da biblioteca sqlite3;
• Armazena os bancos de dados em arquivos;
• Compatível com o padrão SQL92;
• Suporta transações;
• Suporta bancos de dados de até 2 TB.
5. SQLITE
• Primeiro exemplo, Agenda (para variar ...);
• Criando um banco de dados:
• sqlite3 agenda.db agenda
---------------------------
• Criando uma tabela: * id : INTEGER
nome : VARCHAR(30)
CREATE TABLE agenda ( tel : VARCHAR(20)
id INTEGER PRIMARY KEY,
nome VARCHAR(30),
tel VARCHAR(20));
6. SQLITE
• Inserindo dados:
• INSERT INTO agenda(nome, tel) VALUES (‘Pedro’, ‘555-5555’);
• INSERT INTO agenda(nome, tel) VALUES (‘Maria’, ‘333-3333’);
• INSERT INTO agenda(nome, tel) VALUES (‘José’, ‘444-4444’);
• INSERT INTO agenda(nome, tel) VALUES (‘Ana’, ‘666-6666’);
• Para encerrar o SQLITE pressione CONTROL+D;
• Verifique se o arquivo agenda.db foi criado.
7. Módulo SQLITE3
• Módulo compatível com a DB-API;
• Utilizando o módulo:
• from sqlite3 import dbapi2 as sqlite
• Criando uma conexão:
Atenção: O arquivo agenda.db
• con = sqlite.connect('agenda.db') deve estar no diretório corrente,
caso contrário especifique o
caminho completo para o arquivo.
• Obtendo um cursor:
• cursor = con.cursor( )
8. Módulo SQLITE3
• Realizando uma consulta:
• cursor.execute('select * from agenda')
• Obtendo os valores da consulta:
• dados = cursor.fetchall( )
• O método fetchall retorna uma lista com todos os dados da consulta;
• Você pode preferir retornar um número menor de dados utilizando os
métodos fetchone ou fetchsome.
9. Módulo SQLITE3
• Note que os dados retornados pelo fetchall são uma lista:
• [(1, u'Escola Técnica Federal de Palmas', u'63-3225-1205'), (2, u'Aeroporto de Palmas',
u'63-3219-3700'), (3, u'Água e Esgoto', u'0800-644-0195'), (4, u'Energia Elétrica',
u'0800-646-4196'), (5, u'Disque-Denúncia', u'0800-63-1190'), (6, u'Polícia Civil',
u'63-3218-5000'), (7, u'Prefeitura Municipal', u'63-3218-5000'), (8, u'Alcoólicos Anônimos',
u'63-3215-4165')]
• Você pode acessar esses valores pelo índice:
• Nome do primeiro registro: dados[0][1]
• Ou fazer algo com um jeito mais Python:
cursor.execute('SELECT nome, tel FROM agenda ORDER BY nome')
for nome, tel in cursor.fetchall():
print nome, tel
10. Módulo SQLITE3
• Para inserir, remover ou atualizar dados você deve utilizar uma transação;
• Por exemplo:
# -*- coding: latin-1 -*-
from sqlite3 import dbapi2 as sqlite
#Abrindo uma conexão
con = sqlite.connect('agenda.db')
#Obtendo um cursor
cursor = con.cursor()
cursor.execute("INSERT INTO agenda(nome, tel) VALUES('Bruno', '123')")
#Salvando os dados da transação
con.commit()
11. Módulo SQLITE3
• Passando parâmetros;
• É importante prestar atenção a forma como os parâmetros são passados
para evitar ataques de SQL Injection no seu sistema;
• Forma errada:
• cursor.execute('INSERT INTO agenda(nome,tel) VALUES (%s, %s)' % (nome, tel))
• Forma correta:
• cursor.execute('INSERT INTO agenda(nome,tel) VALUES (?, ?)', (nome, tel))
12. Módulo SQLITE3
- O nome dele - Bem, nós perdemos o
Oi, aqui é a escola realmente é Robert’); registro deste ano de
- Nossa, ele DROP TABLE todos os estudantes.
do seu filho. Nós
quebrou algo ? Students;--? Espero que você esteja
estamos tendo um
- De certa forma - É sim. Nós o feliz.
problema com
sim. chamados de - E eu espero que você
computadores.
pequeno Bobby tenha aprendido a tratar
Tables. os dados de entrada.
13. # -*- coding: latin-1 -*- Este é um
from sqlite3 import dbapi2 as sqlite programa
completo !
#Abrindo uma conexão
con = sqlite.connect('agenda.db')
#Obtendo um cursor
cursor = con.cursor()
while True:
opcao = raw_input('Qual a sua opção (a)dicionar, (l)istar ou (s)air: ')
if opcao == 'a':
nome = raw_input('Digite o nome: ')
tel = raw_input('Digite o telefone: ')
cursor.execute('INSERT INTO agenda(nome,tel) VALUES (?, ?)', (nome, tel))
con.commit()
elif opcao == 'l':
cursor.execute('SELECT nome, tel FROM agenda ORDER BY nome')
for nome, tel in cursor.fetchall():
print nome, tel
elif opcao == 's':
break
else:
print 'Digite uma opção válida !'
14. SQLAlchemy
• É uma biblioteca que facilita a utilização de bancos de dados por aplicações
Python;
• O SQLAlchemy faz o mapeamento objecto-relacional entre os objetos Python
a as tabelas de um banco de dados;
• SQLAlchemy é suporta qualquer banco de dados que possua módulo DB-
API;
• A instalação do SQLAlchemy pode ser feita de duas formas:
• Fazendo o download; http://www.sqlalchemy.org/
• Utilizando o setuptools.
15. Setup Tools
• Objetivo: Instalação fácil de pacotes Python;
• Link para download:
• http://pypi.python.org/pypi/setuptools/
• Instalação:
• Windows:
• Execute o arquivo setuptools-0.6c11.win32-py2.6.exe;
• Linux e MacOS:
• sudo sh setuptools-0.6c11-py2.6.egg
16. SQLAlchemy
• Instalação:
• Windows:
• easy_install SQLAlchemy
• Linux e MacOS:
• sudo easy_install SQLAlchemy
17. SQLAlchemy
• Conceitos básicos:
• Você deve criar classes para mapear as tabelas do banco de dados;
• As operações serão feitas apenas sobre as classes, não necessitando
trabalhar com SQL;
• A conexão ao banco de dados é feita através de uma engine;
• As operações com o banco de dados são feitas em uma sessão;
• Uma sessão define uma transação.
18. SQLAlchemy
• Mapeando uma classe em uma tabela:
• É necessário criar uma classe para cada tabela que se queira mapear;
• As próprias classes podem ser utilizadas para criar as tabelas, caso elas
não existam;
• Forma geral:
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Contato(Base):
__tablename__ = 'agenda' Atributo obrigatório
id = Column(Integer, primary_key=True)
nome = Column(String)
tel = Column(String)
19. SQLAlchemy
• Toda classe mapeada é subclasse de declarative_base;
• No SQLAlchemy toda tabela/classe mapeada deve ter uma chave primária;
• Não é necessário criar um construtor para as classes mapeadas;
• Todas as colunas tem um tipo associado (Integer, String, Numeric, etc);
• Se você está utilizando o PostgreSQL ou o SQLite são há necessidade de
especificar o tamanho das colunas, mas para os outros bancos é obrigatório
indicar este tamanho:
class Contato(Base):
__tablename__ = 'agenda'
id = Column(Integer, primary_key=True)
nome = Column(String(30))
tel = Column(String(20))
20. SQLAlchemy
• Com exceção do Oracle e do Firebird, todos os outros bancos de dados têm
suporte a colunas com auto incremento (para as chaves primárias);
• Para o Oracle e Firebird é necessário especificar uma seqüência:
class Contato(Base):
__tablename__ = 'agenda'
id = Column(Integer, Sequence('contato_seq'), primary_key=True)
nome = Column(String(30))
tel = Column(String(20))
21. SQLAlchemy
Nome do SGBD
• Obtendo uma engine:
• engine = create_engine('sqlite:///agenda.db')
URL para o banco de dados
• O nome do SGBD é uma forma do SQLAlchemy localizar o módulo correto,
alguns exemplos de nomes são: sqlite, mysql, postgresql, mssql, oracle, ...
• A URL para o banco de dados é dependente do módulo que se está
utilizando, por isso, deve-se ler a documentação do módulo para saber como
construir a URL;
• Exemplos: mssql://user:passwd@mydsn, oracle://scott:tiger@127.0.0.1:1521/
sidname, mysql://scott:tiger@localhost/foo, ...
• Você pode, na criação, pedir que a engine mostre todos o código SQL
gerado por ela: create_engine('sqlite:///agenda.db', echo=True)
22. SQLAlchemy
• Criando automaticamente as tabelas:
• Para isto, após a definição do mapeamento, utiliza-se o atributo metadata
da classe Base:
Base.metadata.create_all(engine)
• Obtendo uma sessão:
• As sessões estão sempre associadas a uma engine:
Session = sessionmaker(bind=engine)
session = Session()
23. SQLAlchemy
• Gravando objetos no banco de dados:
• session.add(objeto)
• session.commit( )
• Você pode adicionar uma lista de objetos de uma vez só:
• session.add_all([objeto1, objeto2, objeto3])
• Atenção: Lembre-se sempre de após um bloco de atualizações realizar o
commit, pois, caso contrário, os dados não serão persistidos;
• Caso algum erro ocorra, você deve chamar o rollback, para deixar o estado do
banco de dados igual ao do último commit realizado.
24. SQLAlchemy - Consultas
• Pela chave primária:
• bruno = session.query(Contato).get(5)
• Retornando todos os registros:
• contatos = session.query(Contato).all( )
• Ordenando os resultados:
• contatos = session.query(Contato).order_by(Contato.nome).all( )
• Filtrando por um campo:
• pedro = session.query(Contato).filter(nome=”Pedro”).first( )
• Restringindo os resultados:
• Você pode usar o método all, para obter todos os resultados ou first para
obter apenas o primeiro.
25. SQLAlchemy
• Para alterar um registro é preciso: obtê-lo na sessão, modificar seus valores e
fazer commit da sessão:
contato = session.query(Contato).get(5)
contato.tel = '8888-8888'
session.commit()
• Para remover um registro é preciso: obtê-lo, chamar o método delete na
sessão e fazer commit:
contato = session.query(Contato).get(5)
session.delete(contato)
session.commit()
26. SQLAlchemy
• Vamos reproduzir o nosso exemplo anterior criando um novo projeto do
PyDev chamado Agenda;
• Este projeto será composto por dois módulos contato.py e principal.py;
• O módulo contato.py irá conter o mapeamento da classe Contato com a
tabela agenda;
• O módulo principal.py terá o código do programa principal.
27. SQLAlchemy - Módulo contato.py
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Contato(Base):
__tablename__ = 'agenda'
id = Column(Integer, primary_key=True)
nome = Column(String)
tel = Column(String)
def __init__(self, nome, tel):
self.nome = nome
self.tel = tel
28. SQLAlchemy - Módulo principal.py
• Apenas o cabeçalho e os imports:
# -*- coding: latin-1 -*-
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from contato import Contato, Base
import os
• Continua ...
29. engine = create_engine('sqlite:///agenda.db')
Session = sessionmaker(bind=engine)
session = Session()
if not os.path.exists('agenda.db'):
Base.metadata.create_all(engine)
while True:
opcao = raw_input('Qual a sua opção (a)dicionar, (l)istar ou (s)air: ')
if opcao == 'a':
nome = raw_input('Digite o nome: ')
tel = raw_input('Digite o telefone: ')
session.add(Contato(nome, tel))
session.commit()
elif opcao == 'l':
for contato in session.query(Contato).order_by(Contato.nome):
print contato.nome, contato.tel
elif opcao == 's':
break
else:
print 'Digite uma opção válida !'