Objetivos de aprendizado
Depois de ler este artigo, você vai conseguir:
- Conhecer os critérios que definem o banco certo para um projeto Python
- Comparar SQLite, PostgreSQL, MySQL, MongoDB e Redis com as bibliotecas atuais
- Escolher o banco por cenário: Django, FastAPI, bot, script ou cache
Python conversa bem com quase qualquer banco de dados. Há driver maduro para PostgreSQL, MySQL, MongoDB e Redis, e o SQLite já vem na biblioteca padrão. Isso é bom, mas transforma a escolha numa lista longa de opções que parecem equivalentes.
Na prática, a decisão depende de poucas perguntas: que forma têm os seus dados, qual framework você usa, quantos processos gravam ao mesmo tempo e se o código é síncrono ou assíncrono. A seguir, você vê os critérios, cada opção com a biblioteca atual e uma recomendação por cenário.
Quais critérios importam na escolha?#
- Forma dos dados. Usuários, pedidos e pagamentos ligados entre si pedem tabelas, chaves estrangeiras e
JOIN, ou seja, um banco relacional. Documentos com campos que variam muito de um registro para outro se encaixam melhor num banco de documentos. A diferença entre os dois modelos está em SQL ou NoSQL. - Framework. O Django tem ORM próprio e suporta oficialmente cinco bancos relacionais. FastAPI e Flask não impõem nada, e o mais comum é usar SQLAlchemy.
- Concorrência. Um script ou bot de um processo só é diferente de uma API com vários workers gravando ao mesmo tempo.
- Sync ou async. Se o seu código usa
asyncio(FastAPI, bots), prefira um driver com API assíncrona para não travar o loop de eventos. - Operação. Um arquivo SQLite não precisa de servidor. Os outros precisam de host, credenciais, conexões e cópias de segurança.
Quando SQLite basta?#
O módulo sqlite3 faz parte da biblioteca padrão do Python. O SQLite guarda tudo em um arquivo e roda dentro do seu processo, sem servidor separado. É ideal para scripts, ferramentas de linha de comando, protótipos, testes e apps pequenos de um processo só.
import sqlite3
from contextlib import closing
with closing(sqlite3.connect("app.db")) as con:
con.execute("PRAGMA journal_mode=WAL")
con.execute(
"CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, text TEXT NOT NULL)"
)
with con: # commit no fim do bloco, rollback se der erro
con.execute("INSERT INTO notes (text) VALUES (?)", ("olá",))
for row in con.execute("SELECT id, text FROM notes"):
print(row)Um detalhe que pega muita gente: usar a conexão em um with faz commit ou rollback, mas não fecha a conexão. Por isso o exemplo usa contextlib.closing, como a própria documentação sugere.
O limite está na escrita. A documentação do SQLite explica que ele aceita um escritor por vez por arquivo e não é indicado quando muitas máquinas acessam o mesmo banco pela rede. Se o arquivo fica numa pasta que o deploy substitui, os dados vão embora junto.
Por que PostgreSQL é a escolha padrão?#
PostgreSQL é um banco relacional cliente-servidor feito para muitas conexões simultâneas, com transações, índices variados, JSONB e extensões. Para quase todo projeto Python que vai crescer, ele é a escolha com menos chance de arrependimento. Veja mais em o que é PostgreSQL.
As bibliotecas mais usadas:
- psycopg 3 (pacote
psycopg): o driver atual, com APIs síncrona e assíncrona. A documentação do Django o recomenda e avisa que o suporte ao psycopg2 deve ser descontinuado no futuro. - asyncpg: driver só assíncrono, popular com FastAPI.
- SQLAlchemy 2: ORM e toolkit SQL muito usado fora do Django. Funciona com PostgreSQL, MySQL e MariaDB, SQLite, Oracle e SQL Server, e no PostgreSQL aceita psycopg, psycopg2, asyncpg e pg8000.
Com SQLAlchemy, o mesmo código roda em SQLite no seu computador e em PostgreSQL em produção. Só a URL muda: sem DATABASE_URL, o exemplo usa sqlite:///app.db; em produção, defina algo como postgresql+psycopg://usuario:senha@host/banco.
import os
from sqlalchemy import String, create_engine, select
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(80))
engine = create_engine(os.environ.get("DATABASE_URL", "sqlite:///app.db"))
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(User(name="Ana"))
session.commit()
for user in session.scalars(select(User).where(User.name == "Ana")):
print(user.id, user.name)Crie o engine uma vez, ao iniciar o processo. Ele mantém um pool de conexões; criar um por requisição é a receita do erro too many connections. Para produção, instale o driver com pip install "psycopg[binary]" sqlalchemy. Diferenças entre SQLite e PostgreSQL ainda aparecem em tipos e funções, então teste no mesmo banco que vai usar em produção antes de publicar.
E o MySQL ou o MariaDB?#
MySQL e MariaDB são bancos relacionais tão capazes quanto o PostgreSQL para a maioria das aplicações web. O Django suporta os dois e recomenda o driver mysqlclient. Outras opções são o PyMySQL, escrito em Python puro, e o MySQL Connector/Python, da Oracle. No SQLAlchemy, a URL fica mysql+mysqldb:// ou mysql+pymysql://.
Escolha MySQL quando a sua equipe já o conhece, quando você vai integrar com um sistema que já usa MySQL ou quando é o que a sua hospedagem oferece. A comparação detalhada está em PostgreSQL ou MySQL.
Quando MongoDB faz sentido em Python?#
MongoDB guarda documentos parecidos com dicionários Python, sem esquema fixo. Combina com catálogos com atributos variáveis, logs de eventos e perfis que mudam a cada versão do app. Veja o que é MongoDB.
O driver oficial é o PyMongo. Atenção a tutoriais antigos: a MongoDB descontinuou o Motor em 14 de maio de 2025 em favor da API assíncrona do próprio PyMongo (AsyncMongoClient). O Motor recebeu só correções de bugs até 14 de maio de 2026 e, depois disso, só correções críticas até o fim do suporte.
import os
from pymongo import MongoClient
client = MongoClient(os.environ["MONGODB_URI"])
profiles = client["app"]["profiles"]
profiles.update_one(
{"_id": "user-42"},
{"$inc": {"xp": 10}, "$setOnInsert": {"plan": "basic"}},
upsert=True,
)
print(profiles.find_one({"_id": "user-42"}))No Django, o MongoDB não tem suporte oficial. Existe o backend de terceiros django-mongodb-backend, e a documentação do Django avisa que os recursos suportados por backends de terceiros variam bastante. Se o projeto é Django, fique no relacional.
Redis serve como banco principal?#
Redis guarda dados em memória e responde muito rápido. Em Python, o pacote redis traz cliente síncrono e assíncrono (redis.asyncio). Ele é a ferramenta certa para cache, sessões, rate limit, filas de tarefas (Celery e RQ podem usar Redis como broker) e contadores.
Como banco principal, ele exige cuidado: a gravação em disco é configurável, e os dados precisam caber na RAM. Na maioria dos projetos, Redis fica ao lado de um PostgreSQL ou MongoDB, não no lugar deles. A diferença está explicada em Redis como cache ou como banco.
Qual banco escolher em cada cenário?#
| Cenário | Recomendação | Biblioteca |
|---|---|---|
| Script, CLI, protótipo, testes | SQLite | sqlite3 (padrão) |
| Projeto Django | PostgreSQL | ORM do Django + psycopg 3 |
| API com FastAPI ou Flask | PostgreSQL | SQLAlchemy 2 + psycopg 3 ou asyncpg |
| Sistema legado ou equipe que já usa MySQL | MySQL ou MariaDB | mysqlclient ou PyMySQL |
| Documentos com formato variável | MongoDB | PyMongo (sync ou AsyncMongoClient) |
| Cache, sessões, filas | Redis, junto do banco principal | redis (redis.asyncio para async) |
| Bot do Discord ou Telegram pequeno | SQLite, depois PostgreSQL | sqlite3, depois psycopg 3 |
Na dúvida, comece com PostgreSQL e SQLAlchemy (ou o ORM do Django). Você ganha um banco que aguenta crescer e uma camada que esconde boa parte das diferenças entre bancos. Para bots, a análise detalhada está em qual banco usar no bot do Discord.
Quais erros evitar?#
- Montar SQL com f-string. Use sempre parâmetros (
?no sqlite3,%sno psycopg, ou o ORM). F-string com entrada do usuário abre SQL injection. - Abrir uma conexão por requisição. Crie o engine ou o pool uma vez e reutilize.
- Driver síncrono dentro de código async. Uma consulta bloqueante para o loop inteiro do FastAPI ou do bot.
- Credenciais no código. Leia a URL de conexão de uma variável de ambiente, como nos exemplos.
- Nenhuma cópia dos dados. Agende dumps (
pg_dump,mongodump) e teste a restauração antes de precisar dela.
Para publicar a aplicação junto com o banco, veja como hospedar FastAPI, Flask ou Django.
Como fazer isso na Square Cloud#
Na Square Cloud você pode hospedar MongoDB, PostgreSQL, MySQL e Redis a partir do plano Standard (R$ 44,99 por mês); o Hobby não inclui bancos. Você cria o banco no painel (nome, memória e motor), e ele é provisionado em segundos no mesmo datacenter das aplicações, com latência média de cerca de 1 ms. O PostgreSQL é o nativo, sem extensões, e o Redis tem persistência.
Do lado do Python quase nada muda: coloque a URL de conexão completa que o painel entrega numa variável de ambiente da aplicação (DATABASE_URL, MONGODB_URI) e leia com os.environ, como nos exemplos acima. A mudança vale no próximo restart, sem rebuild. O TLS é obrigatório: baixe o certificado no painel e aponte o driver para a CA; no PostgreSQL e no MongoDB, o cliente também apresenta o certificado .pem. No Redis, use rediss://. Como o banco aceita conexões de fora, você pode rodar o mesmo código na sua máquina com o mesmo certificado.
Você tira snapshots manuais quando quiser, e todo plano com bancos inclui também um snapshot automático diário, guardado por 7 dias. Um snapshot pode ser restaurado no mesmo banco, em outro do mesmo motor ou num banco novo, ou baixado como .zip. Veja os motores e planos na página de hospedagem de bancos de dados.
Hospedagem de bancos
MongoDB, PostgreSQL, MySQL e Redis no mesmo datacenter do app
Perguntas frequentes
Qual o melhor banco de dados para Django?
PostgreSQL. O Django suporta oficialmente PostgreSQL, MariaDB, MySQL, Oracle e SQLite, e boa parte dos recursos extras do framework, como campos de array e busca textual, existe só para PostgreSQL. Para começar, o SQLite padrão do projeto funciona.
Python precisa instalar algo para usar SQLite?
Normalmente não. O módulo sqlite3 faz parte da biblioteca padrão do Python, e o SQLite roda dentro do seu processo, sem servidor separado. Algumas distribuições compilam o Python sem ele, então confira se o import funciona.
Ainda devo usar Motor para MongoDB com asyncio?
Não em projeto novo. A MongoDB descontinuou o Motor em maio de 2025 em favor da API assíncrona do próprio PyMongo, que traz a classe AsyncMongoClient. O Motor deixou de receber correções comuns em maio de 2026.
psycopg2 ou psycopg 3?
psycopg 3 (pacote psycopg) para projetos novos. Ele tem suporte a async, e a documentação do Django o recomenda, avisando que o suporte ao psycopg2 deve ser descontinuado no futuro.
Mais em Bancos de dados
Ver todos os 24 artigos- Quanto custa um banco de dados na nuvem?Um banco de dados na nuvem custa de zero a centenas de dólares por mês. Veja o que define o preço: instância, disco, tráfego, snapshots e como estimar o seu.
- Como hospedar um banco de dados (e conectar sua aplicação)Para hospedar um banco de dados, escolha o motor, crie a instância, guarde a string de conexão em variável de ambiente e teste a conexão. Veja o passo a passo.
- O que é Redis e para que serveRedis é um banco de dados em memória que guarda pares chave-valor e estruturas de dados. Veja como funciona, para que serve e quando não usar.
- Como fazer backup do banco de dados (MySQL, PostgreSQL, MongoDB)Faça backup de MySQL, PostgreSQL e MongoDB com mysqldump, pg_dump e mongodump, e restaure o dump. Veja os comandos, como verificar e os erros comuns.