Bancos de Dados Python

SQLModel: Simplificando o Mapeamento de Objetos para Bancos de Dados em Python

Desvende o SQLModel: Simplificando o Mapeamento de Objetos Python para Bancos de Dados Relacionais. Domine o CRUD de forma eficaz!

há 6 meses 3 semanas

Formação Analista de banco de dados
Conheça a formação em detalhes

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:

  1. 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.
  2. 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.
  3. 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.
  4. Relacionamentos entre modelos: É possível definir relacionamentos entre modelos de forma simples, como relacionamentos um-para-muitos e muitos-para-muitos.
  5. 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.

Python - Fundamentos
Curso Python - Fundamentos
Conhecer o curso

Exemplo 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

Python - Collections
Curso Python - Collections
Conhecer o curso

Criaçã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.

Python - Orientação a objetos
Curso Python - Orientação a objetos
Conhecer o curso

Inserindo 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}")

Python - SQLAlchemy ORM
Curso Python - SQLAlchemy ORM
Conhecer o curso

Atualizando 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.

Autor(a) do artigo

Cleyson Lima
Cleyson Lima

Professor, programador, fã de One Piece e finge saber cozinhar. Cleyson é graduando em Licenciatura em Informática pelo IFPI - Campus Teresina Zona Sul, nos anos de 2019 e 2020 esteve envolvido em vários projetos coordenados pela secretaria municipal de educação da cidade de Teresina, onde o foco era introduzir alunos da rede pública no mundo da programação e robótica. Hoje é instrutor dos cursos de Spring na TreinaWeb, mas diz que seu coração sempre pertencerá ao Python.

Todos os artigos

Artigos relacionados Ver todos