Ficha 01 · Drivers e SQL parametrizado
- Conectar BD via driver
- Usar prepared statements
- Gerir transações
- Tratar erros
Parte I · Conexão
Exercício 1 · Configuração segura (10 pts)
Como deves armazenar a senha da BD na aplicação? Indica o que não fazer e o que fazer:
Exercício 2 · Connect padrão (10 pts)
Escreve código Python (usando psycopg2) que: - Lê credenciais de variáveis de ambiente. - Abre conexão. - Executa query simples. - Fecha tudo correctamente.
Parte II · Prepared statements
Exercício 3 · Corrigir SQL injection (15 pts)
Estes 3 fragmentos têm SQL injection. Corrige cada um:
a)
nome = request.form["nome"]
cur.execute(f"SELECT * FROM users WHERE nome = '{nome}'")
b)
ids = "1,2,3" # vem do user
cur.execute(f"SELECT * FROM Cliente WHERE id IN ({ids})")
c)
nome = request.args["nome"]
cur.execute("INSERT INTO Cliente (nome) VALUES ('%s')" % nome)
Exercício 4 · Múltiplos parâmetros (10 pts)
Escreve INSERT que insere um produto com nome, preço e stock vindo de input do utilizador.
Parte III · Transações
Exercício 5 · Transferência (20 pts)
Escreve função transferir(origem, destino, qty) que move dinheiro entre 2 contas como transação atómica. Se algo correr mal, faz rollback.
Exercício 6 · Erros (15 pts)
Que excepções podem ocorrer ao executar query? Como tratar:
a) BD indisponível.
b) Constraint violada (ex.: UNIQUE).
c) Timeout.
Parte IV · Cenário
Exercício 7 · Padrão de acesso (20 pts)
Escreve uma classe ClienteRepository que encapsula acesso à tabela Cliente. Métodos:
get(id)— devolve cliente ou None.get_by_email(email)— idem.list_all()— todos os clientes.create(nome, email)— devolve id.update(id, **kwargs)— actualiza colunas.delete(id)— apaga.
Usa prepared statements em tudo. Aceita conn no construtor (dependency injection).