Você está na página 1de 29

Python - Aula 4

Bruno Gama Catão


Bancos de Dados
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.


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.


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.


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));
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.


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( )
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.
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
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()
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))


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.
# -*- 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 !'
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.
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
SQLAlchemy

• Instalação:

• Windows:

• easy_install SQLAlchemy

• Linux e MacOS:

• sudo easy_install SQLAlchemy


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.


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)
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))
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))
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)
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()
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.
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.
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()
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.


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
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 ...
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 !'

Você também pode gostar