A persistência de dados é uma parte fundamental no desenvolvimento de software, e quando se trata de aplicativos que utilizam bancos de dados relacionais, a tarefa de mapear objetos Python para tabelas de banco de dados pode ser complexa e propensa a erros. Felizmente, o SQLModel é uma biblioteca Python que simplifica significativamente esse processo. Neste artigo, exploraremos o SQLModel, suas principais funcionalidades, vantagens e desvantagens, e como ele pode ser uma ferramenta valiosa para desenvolvedores que trabalham com bancos de dados relacionais em Python.
O que é o SQLModel?
O SQLModel é uma biblioteca Python que simplifica o mapeamento de objetos para bancos de dados relacionais. Ele foi inspirado pelo SQLAlchemy, outro popular mapeador objeto-relacional (ORM) em Python, mas possui uma abordagem mais simples e intuitiva. O SQLModel é projetado para ser fácil de usar e permite que os desenvolvedores definam modelos de dados em Python que são automaticamente traduzidos em esquemas de banco de dados e operações CRUD (Create, Read, Update, Delete).
A principal vantagem do SQLModel é sua simplicidade e a capacidade de definir modelos de dados de forma declarativa, sem a necessidade de escrever consultas SQL manualmente. Ele suporta vários bancos de dados, incluindo SQLite, PostgreSQL e MySQL, tornando-o uma escolha versátil para projetos Python que precisam interagir com diferentes sistemas de gerenciamento de banco de dados.
Principais funcionalidades
O SQLModel oferece uma variedade de funcionalidades que facilitam o mapeamento de objetos para bancos de dados relacionais:
- Declaração de modelos: Os modelos de dados são definidos como classes Python, onde cada atributo da classe representa uma coluna na tabela do banco de dados. O SQLModel automaticamente cria o esquema do banco de dados com base na definição da classe.
- Operações CRUD automáticas: Com o SQLModel, você pode realizar operações CRUD (Create, Read, Update, Delete) em seus modelos de dados de forma simples e intuitiva. Não é necessário escrever consultas SQL complexas.
- Validações de dados: O SQLModel oferece suporte para validações de dados, garantindo que os valores inseridos em um modelo correspondam às regras definidas na classe do modelo.
- Relacionamentos entre modelos: É possível definir relacionamentos entre modelos de forma simples, como relacionamentos um-para-muitos e muitos-para-muitos.
- Suporte a tipos de dados personalizados: Além dos tipos de dados padrão, o SQLModel permite que você defina tipos de dados personalizados para suas colunas de banco de dados.
Curso Python - Fundamentos
Conhecer o cursoExemplo prático
Agora vamos para um simples exemplo para entendermos como usar o SQLModel em um projeto Python. Imagine que tenhamos uma tabela SQL chamada curso
com as seguintes colunas:
- id
- titulo
- descricao
- carga_horaria
- qtd_exercicios
id | titulo | descricao | carga_horaria | qtd_exercicios |
---|---|---|---|---|
1 | Python - Fundamentos | Curso de fundamentos sobre a linguagem Python | 101 | 40 |
2 | Python - Orientação a objetos | Curso sobre orientação a objetos com a linguagem Python | 121 | 34 |
3 | Python - SQLAlchemy ORM | Curso sobre a ORM SQLAlchemy do Python | 251 | 33 |
Nosso objetivo com esse exemplo é conseguir criar a tabela exemplificada acima com SQLModel e realizar as operações de CRUD nessa tabela, para esse exemplo nós vamos utilizar o SQLite para simplificar o ambiente de desenvolvimento.
Preparação do projeto
Primeiramente vamos criar um ambiente virtual para não termos que instalar o SQLModel de maneira global em nossa máquina, para isso execute o seguinte comando:
# Linux ou macOS
python3 -m venv .venv
sourve .venv/bin/activate
# Windows
python -m venv .venv
.venv\Scripts\Activate
Agora que temos o ambiente virtual criado e ativado, vamos prosseguir para a instalação do SQLModel com o seguinte comando:
pip install sqlmodel
Curso Python - Collections
Conhecer o cursoCriação do model
Agora que já temos o SQLModel instalado podemos escrever o nosso código Python, vamos criar um arquivo chamado app.py
que irá conter o nosso código. Inicialmente iremos colocar o seguinte código:
from typing import Optional
from sqlmodel import Field, SQLModel
class Curso(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titulo: str
descricao: str
carga_horaria: int
qtd_exercicios: int
Com isso já temos o código da classe que irá representar a nossa tabela no banco. Veja que o SQLModel se utiliza das tipagens providas para definir as caracteristcias das colunas que serão criadas na tabela do banco de dados.
Ou seja, se um atributo da classe foi tipado como str
a respectiva coluna no banco de dados terá o tipo VARCHAR
e caso não informemos que o tipo é Optinal
a coluna será NOT NULL
. Além disso, caso queira ter um maior controle sobre a DDL que irá gerar a coluna você pode utilizar a classe Field
para passar mais informações, como foi feito para o atributo id
.
Criando as tabelas
Para não termos que criar a tabela manualmente no banco de dados, podemos fazer com que o próprio SQLModel crie essas tabelas:
from typing import Optional
from sqlmodel import Field, SQLModel, create_engine
class Curso(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titulo: str
descricao: str
carga_horaria: int
qtd_exercicios: int
engine = create_engine("sqlite:///curso.db", echo=True)
SQLModel.metadata.create_all(engine)
Utilizamos a função create_engine
do SQLModel para criar uma engine que será responsável prover as conexões com o banco de dados, logo em seguida utilizamos a função create_all
presente em metadata
da classe SQLModel
para que todos os modelos presentes no contexto atual sejam criadas no banco de dados.
Ao executarmos esse código com o comando python [app.py](http://app.py)
veremos uma saída semelhante a essa no terminal:
2023-10-02 14:32:40,999 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2023-10-02 14:32:40,999 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("curso")
2023-10-02 14:32:40,999 INFO sqlalchemy.engine.Engine [raw sql] ()
2023-10-02 14:32:40,999 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info("curso")
2023-10-02 14:32:40,999 INFO sqlalchemy.engine.Engine [raw sql] ()
2023-10-02 14:32:41,000 INFO sqlalchemy.engine.Engine
CREATE TABLE curso (
id INTEGER NOT NULL,
titulo VARCHAR NOT NULL,
descricao VARCHAR NOT NULL,
carga_horaria INTEGER NOT NULL,
qtd_exercicios INTEGER NOT NULL,
PRIMARY KEY (id)
)
2023-10-02 14:32:41,000 INFO sqlalchemy.engine.Engine [no key 0.00007s] ()
2023-10-02 14:32:41,012 INFO sqlalchemy.engine.Engine COMMIT
Isso informa que a SQL de criação da tabela foi executada e inclusive veremos que um arquivo chamado curso.db
foi criado no mesmo nível do nosso arquivo app.py
.
Curso Python - Orientação a objetos
Conhecer o cursoInserindo dados
Agora que já temos o banco criado, podemos começar a realizar operações com o SQLModel, para inserirmos dados na tabela, basta criarmos uma instância do modelo e então utilizar uma Session do SQLModel para adicionar essa instancia e então submeter as alterações realizadas, isso pode ser feito da seguinte maneira:
from typing import Optional
from sqlmodel import Field, SQLModel, create_engine, Session
class Curso(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titulo: str
descricao: str
carga_horaria: int
qtd_exercicios: int
engine = create_engine("sqlite:///curso.db", echo=True)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
curso_python = Curso(
titulo="Curso de Python",
descricao="Curso intermediário de Python",
carga_horaria=40,
qtd_exercicios=20,
)
session.add(curso_python)
session.commit()
Veja que criamos uma instância da classe Session
e para ela passamos a nossa engine
, uma vez que tenhamos a Session criada, basta passarmos as instâncias do modelo para o método add
e por fim, executar o método commit
para persistir as alterações no banco de dados.
Ao executarmos o código acima, veremos a seguinte saída no terminal:
2023-10-02 14:41:40,602 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2023-10-02 14:41:40,602 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("curso")
2023-10-02 14:41:40,602 INFO sqlalchemy.engine.Engine [raw sql] ()
2023-10-02 14:41:40,602 INFO sqlalchemy.engine.Engine COMMIT
2023-10-02 14:41:40,603 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2023-10-02 14:41:40,604 INFO sqlalchemy.engine.Engine INSERT INTO curso (titulo, descricao, carga_horaria, qtd_exercicios) VALUES (?, ?, ?, ?)
2023-10-02 14:41:40,604 INFO sqlalchemy.engine.Engine [generated in 0.00012s] ('Curso de Python', 'Curso intermediário de Python', 40, 20)
2023-10-02 14:41:40,605 INFO sqlalchemy.engine.Engine COMMIT
Veja na linha 6 a SQL executada pelo SQLModel para realizar a inserção dos dados no banco.
Consultando dados
Para realizar consultas com o SQLModel, nós utilizamos a função select
para montarmos a query de consulta que será realizada e em seguida usamos o método execute
da Session para realizar a consulta no banco. Veja como podemos realizar diferentes consultas com o SQLModel:
from typing import Optional
from sqlmodel import Field, SQLModel, create_engine, Session, select
class Curso(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titulo: str
descricao: str
carga_horaria: int
qtd_exercicios: int
engine = create_engine("sqlite:///curso.db", echo=True)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
# Consulta todos os cursos
query = select(Curso)
cursos = session.exec(query).all()
print("Todos os cursos:")
for curso in cursos:
print(f"Curso: {curso.titulo}")
# Consulta um curso específico pelo id
query = select(Curso).where(Curso.id == 1)
curso = session.exec(query).first()
print(f"Curso: {curso.titulo}")
# Consulta um curso específico pelo título com like
query = select(Curso).where(Curso.titulo.like("%Python%"))
curso = session.exec(query).first()
print(f"Curso: {curso.titulo}")
Curso Python - SQLAlchemy ORM
Conhecer o cursoAtualizando dados
Para podermos realizar edições basta primeiramente realizarmos uma consulta para obter uma instância do modelo que queremos editar, então realizar as devidas alterações e por fim excutar o método commit
da session para que as alterações realizadas no modelo sejam persistidas no banco de dados.
from typing import Optional
from sqlmodel import Field, SQLModel, create_engine, Session, select
class Curso(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titulo: str
descricao: str
carga_horaria: int
qtd_exercicios: int
engine = create_engine("sqlite:///curso.db", echo=True)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
# Consulta o curso que deseja alterar
query = select(Curso).where(Curso.id == 1)
curso = session.exec(query).first()
# Altera os dados do curso
curso.titulo = "Curso de Python editado"
curso.descricao = "Descrição do curso de Python editado"
curso.carga_horaria = 40
curso.qtd_exercicios = 30
# Salva as alterações no banco de dados
session.commit()
Exclusão de dados
Para realizar uma remoção com SQLModel, nós precisamos buscar a instância do que modelo que queremos remover e então passar essa instancia para o método delete
da session e por fim executar o commit
para persistir as alterações no banco de dados:
from typing import Optional
from sqlmodel import Field, SQLModel, create_engine, Session, select
class Curso(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titulo: str
descricao: str
carga_horaria: int
qtd_exercicios: int
engine = create_engine("sqlite:///curso.db", echo=True)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
# Consulta o curso que deseja remover
query = select(Curso).where(Curso.id == 1)
curso = session.exec(query).first()
# Remove o curso
session.delete(curso)
session.commit()
Conclusão
O SQLModel é uma biblioteca Python poderosa que simplifica o mapeamento de objetos para bancos de dados relacionais. Com sua abordagem declarativa e facilidade de uso, ele é uma escolha atraente para projetos que desejam minimizar a complexidade do acesso a bancos de dados e reduzir a quantidade de código repetitivo. No entanto, é importante considerar as necessidades específicas do seu projeto, pois em cenários muito complexos, outras soluções ORM mais avançadas podem ser mais adequadas. Em geral, o SQLModel é uma ferramenta valiosa que pode acelerar o desenvolvimento de aplicativos Python que dependem de bancos de dados relacionais.
Por fim, caso queira aprender mais sobre ORM’s no Python, saiba que aqui na TreinaWeb temos o curso Python - SQLAlchemy ORM que possui 04h11 de vídeo e um total de 33 exercícios.
Veja quais são os tópicos abordados durante o curso Python - SQLAlchemy ORM:
- O que é o SQLAlchemy e como o ORM funciona;
- Como instalar o SQLAlchemy utilizando o PIP em qualquer sistema operacional através do PyCharm;
- Como utilizar o SQLAlchemy para conexão com bancos de dados MySQL;
- Como mapear entidades utilizando o modo declarativo;
- Como mapear entidades utilizando os Schemas;
- Como adicionar, editar e remover registros do banco de dados;
- Como listar, filtrar, buscar e ordenar registros do banco de dados;
- Como implementar os relacionamentos 1/N e N/N com o SQLALchemy;
- Como utilizar o Eager Loading na listagem de dados com relacionamentos;
- Como configurar o modo CASCADE para garantir a integridade do banco de dados na exclusão de registros.