Jocilé Serra
Jocilé Serra07/06/2024 11:40
Compartilhe

Banco de Dados Relacionais com Python e SQLite

    Neste artigo, vamos abordar os conceitos fundamentais de bancos de dados relacionais e como podemos interagir com eles usando a Python DB API. Este conteúdo é essencial para qualquer programador que deseja trabalhar com bancos de dados, principalmente em aplicações desenvolvidas em Python.

    1. Introdução aos Bancos de Dados

    O que é um Banco de Dados?

    Os bancos de dados são coleções organizadas de dados, geralmente armazenados e acessados eletronicamente a partir de um sistema de computador. Eles são essenciais para armazenar, gerenciar e recuperar informações de forma eficiente e segura.

    Tipos de Bancos de Dados

    Existem vários tipos de bancos de dados, incluindo:

    • Relacionais: Organizam os dados em tabelas.
    • Não Relacionais: Incluem bancos de dados de documentos, chave-valor, colunares e gráficos.
    • Orientados a Objetos: Armazenam dados na forma de objetos.

    O tipo mais comum é o banco de dados relacional, que utiliza tabelas para organizar os dados.

    O Papel do SGBD

    Os Sistemas de Gerenciamento de Banco de Dados (SGBD) são softwares que interagem com o usuário, outras aplicações e o próprio banco de dados para capturar e analisar os dados. Exemplos populares incluem MySQL, PostgreSQL, SQLite, Oracle Database, Microsoft SQL Server e MariaDB.

    2. Introdução aos Bancos de Dados Relacionais

    Estrutura das Tabelas

    Um banco de dados relacional organiza os dados em tabelas, cada uma composta de linhas (registros) e colunas (campos). Por exemplo, uma tabela 'Clientes' pode ter os campos 'ID', 'nome', 'email' e 'telefone'.

    Chaves Primárias e Estrangeiras

    • Chave Primária: Uma coluna (ou conjunto de colunas) cujo valor é único para cada registro, garantindo a identificação única dos registros.
    • Chave Estrangeira: Um campo em uma tabela que corresponde à chave primária de outra tabela, estabelecendo relações entre as tabelas.

    Relacionamentos entre Tabelas

    Os bancos de dados relacionais permitem criar relações 'um para um', 'um para muitos' e 'muitos para muitos', facilitando consultas complexas que unem dados de várias tabelas.

    3. SQL (Structured Query Language)

    O SQL é a linguagem usada para interagir com bancos de dados relacionais. Com SQL, podemos:

    • Criar tabelas
    • Inserir, atualizar e deletar registros
    • Executar consultas para buscar dados

    4. Python DB API

    Conectando-se a um Banco de Dados

    A primeira etapa para trabalhar com um banco de dados em Python é estabelecer uma conexão usando a Python DB API. Por exemplo:

    import sqlite3
    conn = sqlite3.connect('example.db')
    

    Inserindo Registros

    Para inserir registros, usamos a operação INSERT do SQL. Exemplo:

    cursor = conn.cursor()
    cursor.execute("INSERT INTO Clientes (nome, email) VALUES ('João', 'joao@example.com')")
    conn.commit()
    

    Atualizando Registros

    A operação UPDATE é usada para modificar registros existentes. Exemplo:

    cursor.execute("UPDATE Clientes SET email = 'joao_novo@example.com' WHERE nome = 'João'")
    conn.commit()
    

    Deletando Registros

    A operação DELETE remove registros. Exemplo:

    cursor.execute("DELETE FROM Clientes WHERE nome = 'João'")
    conn.commit()
    

    Operações em Lote

    Para inserir muitos registros de uma vez, usamos o método executemany():

    data = [('Maria', 'maria@example.com'), ('Carlos', 'carlos@example.com')]
    cursor.executemany("INSERT INTO Clientes (nome, email) VALUES (?, ?)", data)
    conn.commit()
    

    Consultas com Resultados

    • Único Resultado: Utilizamos o método fetchone() para recuperar um único registro.
    cursor.execute("SELECT * FROM Clientes WHERE nome = 'Maria'")
    result = cursor.fetchone()
    
    • Múltiplos Resultados: Utilizamos o método fetchall() para recuperar todos os registros.
    cursor.execute("SELECT * FROM Clientes")
    results = cursor.fetchall()
    

    Trabalhando com Resultados de Consulta

    Os resultados são retornados como tuplas por padrão, mas podemos usar a classe sqlite3.Row ou uma row_factory customizada para melhor adequação.

    5. Boas Práticas em Consultas SQL

    Segurança e Eficiência

    Ao escrever consultas SQL em Python, devemos:

    • Evitar a concatenação de strings nas consultas
    • Usar consultas parametrizadas para prevenir ataques de injeção SQL

    Exemplo de Consulta Parametrizada

    cursor.execute("SELECT * FROM Clientes WHERE nome = ?", ('Maria',))
    

    6. Gerenciando Transações

    A Python DB API permite gerenciar transações, o que é crucial para manter a integridade dos dados. Exemplo:

    try:
      conn.execute("BEGIN TRANSACTION")
      cursor.execute("UPDATE Clientes SET email = 'maria_nova@example.com' WHERE nome = 'Maria'")
      conn.commit()
    except:
      conn.rollback()
      raise
    

    Funções para manipular tabelas no SQLite.

    Para adicionar comandos SQL importamos o módulo sqlite3, e usamos a função cursor.execute().

    Criar Banco de dados

    import sqlite3
    from pathlib import Path
    ROOT_PATH = Path(__file__).parent
    conexao = sqlite3.connect(ROOT_PATH / "teste_banco.sqlite")
    cursor = conexao.cursor()
    

    Criar tabela

    def criar_tabela(conexao, cursor):
      cursor.execute(
      "CREATE TABLE clientes (id INTEGER PRIMARY KEY AUTOINCREMENT, nome VARCHAR(100), email VARCHAR(150))"
      )
      conexao.commit()
    criar_tabela(conexao, cursor)
    

    Inserir um registro

    def inserir_registro(conexao, cursor, nome, email):
      data = (nome, email)
      cursor.execute("INSERT INTO clientes (nome, email) VALUES (?,?);", data)
      conexao.commit()
    inserir_registro(conexao, cursor, "João", "joao@gmail.com")
    

    Atualizar um registro

    def atualizar_registro(conexao, cursor, nome, email, id):
      data = (nome, email, id)
      cursor.execute("UPDATE clientes SET nome=?, email=? WHERE id=?;", data)
      conexao.commit()
    atualizar_registro(conexao, cursor, "João Atualizado", "joao.atualizado@gmail.com", 1)
    

    Inserir vários registros

    def inserir_varios(conexao, cursor, dados):
      cursor.executemany("INSERT INTO clientes (nome, email) VALUES (?,?)", dados)
      conexao.commit()
    dados = [
      ("Guilherme", "guilherme@gmail.com"),
      ("Chappie", "chappie@gmail.com"),
      ("Melaine", "melaine@gmail.com"),
      ]
    inserir_varios(conexao, cursor, dados)
    

    Excluir um registro

    def excluir_registro(conexao, cursor, id):
      data = (id,)
      cursor.execute("DELETE FROM clientes WHERE id=?;", data)
      conexao.commit()
    excluir_registro(conexao, cursor, 2)
    

    Recuperar um registro

    def recuperar_cliente(cursor, id):
      cursor.execute("SELECT email, id, nome FROM clientes WHERE id=?", (id,))
      return cursor.fetchone()
    cliente = recuperar_cliente(cursor, 5)
    print(cliente)
    

    Recuperar um dicionário do registro

    É necessário um novo cursor para converter a tupla em dicionário, para isso adicione:

    cursor.row_factory = sqlite3.Row

    
    def recuperar_cliente(cursor, id):
      cursor.execute("SELECT email, id, nome FROM clientes WHERE id=?", (id,))
      return cursor.fetchone()
    cliente = recuperar_cliente(cursor, 5)
    print(dict(cliente))
    print(cliente["email"], cliente["id"], cliente["nome"])
    print(f'Seja bem vindo ao sistema {cliente["nome"]}')
    

    Listar os nomes do dicionário de registros

    def listar_clientes(cursor):
      return cursor.execute("SELECT * FROM clientes ORDER BY nome DESC;")
    clientes = listar_clientes(cursor)
    for cliente in clientes:
      print(dict(cliente))
    

    Conclusão

    Compreender os conceitos de bancos de dados relacionais e saber como interagir com eles usando Python é essencial para o desenvolvimento de aplicações robustas e eficientes. Ao seguir boas práticas e usar as ferramentas adequadas, podemos garantir a segurança e a integridade dos nossos dados.

    Este artigo cobriu os fundamentos e práticas básicas. À medida que você se aprofunda, explorará tópicos mais avançados e específicos para suas necessidades de desenvolvimento.

    Esse conteúdo foi anotado da trilha Desenvolvedor Python.

    Compartilhe
    Comentários (0)