SQLAlchemy é uma biblioteca de mapeamento objeto-relacional SQL em código aberto desenvolvido para a linguagem de programação Python e disponibilizado sobre a licença MIT.[2]

SQLAlchemy
Autor Michael Bayer[1]
Versão estável 0.9.8 (13 de outubro de 2014; há 9 anos)
Escrito em Python
Sistema operacional Multiplataforma
Gênero(s) Mapeamento objeto-relacional
Licença Licença MIT
Estado do desenvolvimento Ativo
Página oficial SQLAlchemy.org

O SQLAlchemy fornece "um conjunto completo e bem conhecido de modelos de persistência de nível corporativo, projetado para eficiência e alta performance de acesso a banco de dados, adaptado em uma linguagem de domínio simples e Pytônica". Sua filosofia é que bancos de dados SQL se comportem cada vez menos como coleções de objetos, em que mais tamanho e performance comecem a importar, enquanto coleções de objeto se comportem cada vez menos como tabelas e linhas, no qual mais abstração começa a importar. Por esta razão o SQLAlchemy adotou o padrão mapeador de dados (como o Hibernate para Java) em vez do padrão de registro ativo usado por vários outros mapeadores objeto-relacional.[3] Entretanto, plugins adicionais como Elixir e declarative permitem aos usuários desenvolverem usando sintaxe declarativa.

O SQLAlchemy foi lançado em fevereiro de 2006 e rapidamente se tornou uma das ferramentas de mapeamento objeto-relacional mais utilizadas juntamente com o ORM do Django, na comunidade Python.

Exemplo editar

O exemplo que se segue representa um relacionamento n-para-1 entre filmes e seus diretores. É mostrado como classes Python definidas pelo usuário criam as tabelas de banco de dados adequadas, como instâncias com relacionamentos são criadas a partir de ambos os lados da relação e, finalmente, como os dados podem ser consultados - ilustrando consultas SQL geradas automaticamente para o carregamento preguiçoso (lazy) e ansioso (eager).

Definição de esquema editar

Criando duas classes Python e suas relativas tabelas de banco de dados no SGBD:

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, sessionmaker

Base = declarative_base()
 
class Filme(Base):
    __tablename__ = 'filmes'
 
    id = Column(Integer, primary_key=True)
    titulo = Column(String(255), nullable=False)
    ano = Column(Integer)
    dirigido_por = Column(Integer, ForeignKey('diretores.id'))
 
    diretor = relation("Diretor", backref='filmes', lazy=False)
 
    def __init__(self, titulo=None, ano=None):
        self.titulo = titulo
        self.ano = ano
    def __repr__(self):
        return "Filme(%r, %r, %r)" % (self.titulo, self.ano, self.diretor)
 
class Diretor(Base):
    __tablename__ = 'diretores'
 
    id = Column(Integer, primary_key=True)
    nome = Column(String(50), nullable=False, unique=True)
 
    def __init__(self, nome=None):
        self.nome = nome
 
    def __repr__(self):
        return "Diretor(%r)" % (self.nome)
 
engine = create_engine('dbms://user:pwd@host/dbname')
Base.metadata.create_all(engine)

Inserção de dados editar

A inserção de filmes e seus diretores pode ser alcançada através das duas entidades:

Session = sessionmaker(bind=engine)
session = Session()

f1 = Filme("Star Trek", 2009)
f1.diretor = Diretor("JJ Abrams")

d2 = Diretor("George Lucas")
d2.filmes = [Filme("Guerra nas Estrelas", 1977), Filme("THX 1138", 1971)]

try:
    session.add(f1)
    session.add(d2)
    session.commit()
except:
    session.rollback()

Consulta editar

alldata = session.query(Filme).all()
for somedata in alldata:
    print somedata

O SQLAlchemy envia a seguinte consulta para o SGBD (omitindo os apelidos - aliases):

SELECT filmes.id, filmes.titulo, filmes.ano, filmes.dirigido_por, diretores.id, diretores.nome 
FROM filmes LEFT OUTER JOIN diretores ON diretores.id = filmes.dirigido_por

A saída:

Filme('Star Trek', 2009L, Diretor('JJ Abrams'))
Filme('Guerra nas Estrelas', 1977L, Diretor('George Lucas'))
Filme('THX 1138', 1971L, Diretor('George Lucas'))

Definindo lazy=True (padrão), o SQLAlchemy primeiro enviaria uma consulta para obter a lista de filmes e apenas quando necessário (preguiçoso - lazy) para cada diretor uma consulta para obter o nome do diretor correspondente:

SELECT filmes.id, filmes.titulo, filmes.ano, filmes.dirigido_por 
FROM filmes

SELECT diretores.id, diretores.nome
FROM diretores 
WHERE diretores.id = %s

Ver também editar

Ligações externas editar

Referências