A biblioteca Python mais simples e transparente para abstração SQL multi-banco de dados.
Diferente de ORMs pesados como SQLAlchemy, SQLBridge permite que você escreva SQL padrão simples e ele traduz automaticamente para qualquer banco de dados suportado.
- ✅ SQL Nativo: Escreva SQL padrão, sem aprender nova sintaxe
- ✅ Detecção Automática: Detecta o dialeto automaticamente pela conexão
- ✅ Transparente: Funciona com qualquer driver DB-API 2.0
- ✅ Leve: Sem overhead de ORM, zero dependências
- ✅ Inteligente: Traduz tipos, funções e sintaxes automaticamente
✅ MySQL / MariaDB
✅ PostgreSQL
✅ Oracle Database
✅ Microsoft SQL Server
✅ IBM DB2
✅ IBM Informix
✅ SQLite
| Feature | MySQL | PostgreSQL | Oracle | SQL Server | DB2 | Informix | SQLite |
|---|---|---|---|---|---|---|---|
| AUTO_INCREMENT | ✅ | ✅ SERIAL | ✅ IDENTITY | ✅ IDENTITY | ✅ IDENTITY | ✅ SERIAL | ✅ AUTOINCREMENT |
| BOOLEAN | ✅ TINYINT(1) | ✅ Nativo | ✅ NUMBER(1) | ✅ BIT | ✅ SMALLINT | ✅ Nativo | ✅ INTEGER |
| LIMIT/OFFSET | ✅ Nativo | ✅ Nativo | ✅ FETCH | ✅ FETCH | ✅ FETCH | ✅ SKIP/FIRST | ✅ Nativo |
| DATE_ADD | ✅ Nativo | ✅ + INTERVAL | ✅ + INTERVAL | ✅ DATEADD | ✅ + DAYS | ✅ + INTERVAL | ✅ datetime() |
| CONCAT | ✅ CONCAT() | ✅ || | ✅ || | ✅ + | ✅ || | ✅ || | ✅ || |
| CTEs | ✅ 8.0+ | ✅ 8.4+ | ✅ 9i+ | ✅ 2005+ | ✅ 9.5+ | ✅ | ✅ 3.8.3+ |
| Window Functions | ✅ 8.0+ | ✅ 8.4+ | ✅ 8.1.6+ | ✅ 2005+ | ✅ 9.5+ | ✅ | ✅ 3.25.0+ |
pip install sqlbridgefrom sqlbridge import SQLBridge
import psycopg2
# 1. Você cria a conexão com o banco que escolher (PostgreSQL neste exemplo)
conn = psycopg2.connect("postgresql://localhost/mydb")
# 2. SQLBridge detecta automaticamente que é PostgreSQL
bridge = SQLBridge(conn) # Detecta: "postgresql"
# 3. Escreva SQL padrão - o mesmo código funciona em qualquer banco!
sql = """
CREATE TABLE users (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
"""
# 4. SQLBridge traduz automaticamente para o dialeto PostgreSQL
bridge.execute(sql)
# SQL traduzido executado:
# CREATE TABLE users (
# id SERIAL PRIMARY KEY, -- AUTO_INCREMENT → SERIAL
# name VARCHAR(100) NOT NULL,
# email VARCHAR(255) UNIQUE,
# created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- DATETIME → TIMESTAMP
# )- Você escolhe o banco e cria a conexão (MySQL, PostgreSQL, etc.)
- SQLBridge detecta automaticamente o dialeto pela conexão
- Você escreve SQL padrão - sempre o mesmo código
- SQLBridge traduz para o dialeto específico do banco conectado
Seu código (sempre o mesmo):
sql = """
CREATE TABLE users (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
is_active BOOLEAN DEFAULT TRUE
)
"""Tradução automática para cada banco:
┌─────────────────────────────────────────────────────────────────┐
│ 🐬 MySQL │
├─────────────────────────────────────────────────────────────────┤
│ CREATE TABLE users ( │
│ id INTEGER AUTO_INCREMENT PRIMARY KEY, │
│ name VARCHAR(100), │
│ is_active TINYINT(1) DEFAULT 1 │
│ ) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🐘 PostgreSQL │
├─────────────────────────────────────────────────────────────────┤
│ CREATE TABLE users ( │
│ id SERIAL PRIMARY KEY, │
│ name VARCHAR(100), │
│ is_active BOOLEAN DEFAULT TRUE │
│ ) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🔶 Oracle │
├─────────────────────────────────────────────────────────────────┤
│ CREATE TABLE users ( │
│ id NUMBER GENERATED AS IDENTITY PRIMARY KEY, │
│ name VARCHAR(100), │
│ is_active NUMBER(1) DEFAULT 1 │
│ ) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🪟 SQL Server │
├─────────────────────────────────────────────────────────────────┤
│ CREATE TABLE users ( │
│ id INTEGER IDENTITY(1,1) PRIMARY KEY, │
│ name VARCHAR(100), │
│ is_active BIT DEFAULT 1 │
│ ) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 💾 SQLite │
├─────────────────────────────────────────────────────────────────┤
│ CREATE TABLE users ( │
│ id INTEGER AUTOINCREMENT PRIMARY KEY, │
│ name VARCHAR(100), │
│ is_active INTEGER DEFAULT 1 │
│ ) │
└─────────────────────────────────────────────────────────────────┘Seu código:
sql = "SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20"Tradução automática:
┌─────────────────────────────────────────────────────────────────┐
│ 🐬 MySQL / 🐘 PostgreSQL / 💾 SQLite │
├─────────────────────────────────────────────────────────────────┤
│ SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🔶 Oracle / 🪟 SQL Server / 🔷 DB2 │
├─────────────────────────────────────────────────────────────────┤
│ SELECT * FROM users ORDER BY id │
│ OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🔵 Informix │
├─────────────────────────────────────────────────────────────────┤
│ SELECT SKIP 20 FIRST 10 * FROM users ORDER BY id │
└─────────────────────────────────────────────────────────────────┘Seu código:
sql = "SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users"Tradução automática:
┌─────────────────────────────────────────────────────────────────┐
│ 🐬 MySQL │
├─────────────────────────────────────────────────────────────────┤
│ SELECT CONCAT(first_name, ' ', last_name) AS full_name │
│ FROM users │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🐘 PostgreSQL / 🔶 Oracle / 🔷 DB2 / 🔵 Informix / 💾 SQLite │
├─────────────────────────────────────────────────────────────────┤
│ SELECT first_name || ' ' || last_name AS full_name │
│ FROM users │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🪟 SQL Server │
├─────────────────────────────────────────────────────────────────┤
│ SELECT first_name + ' ' + last_name AS full_name │
│ FROM users │
└─────────────────────────────────────────────────────────────────┘💡 A mágica: Você escreve uma vez, SQLBridge traduz para todos os bancos!
SQLBridge inclui um Query Builder poderoso para construir queries programaticamente:
from sqlbridge import SQLBridge, QueryBuilder, table
import sqlite3
conn = sqlite3.connect('mydb.db')
bridge = SQLBridge(conn)
# SELECT com Query Builder
query = (QueryBuilder('users')
.select('id', 'name', 'email')
.where('age', '>', 18)
.where('city', '=', 'São Paulo')
.order_by('name', 'ASC')
.limit(10))
# Executar query
results = bridge.execute_builder(query)
# Ou construir SQL para ver
print(query.build()) # SELECT id, name, email FROM users WHERE age > ? AND city = ? ORDER BY name ASC LIMIT 10
print(query.get_params()) # [18, 'São Paulo']# INSERT
query = (QueryBuilder('users')
.insert({
'name': 'Alice',
'email': 'alice@example.com',
'age': 30
}))
bridge.execute_builder(query)
# UPDATE
query = (QueryBuilder('users')
.update({'age': 31})
.where('name', '=', 'Alice'))
bridge.execute_builder(query)
# DELETE
query = (QueryBuilder('users')
.delete()
.where('is_active', '=', 0))
bridge.execute_builder(query)
# JOIN
query = (QueryBuilder('posts')
.select('posts.title', 'users.name')
.inner_join('users', 'posts.user_id = users.id')
.where('posts.views', '>', 100)
.order_by('posts.views', 'DESC'))
results = bridge.execute_builder(query)
# GROUP BY e HAVING
query = (QueryBuilder('orders')
.select('customer_id', 'COUNT(*) as order_count', 'SUM(total) as total_spent')
.group_by('customer_id')
.having('COUNT(*) > ?', 5)
.order_by('total_spent', 'DESC'))
results = bridge.execute_builder(query)
# Helper function
query = (table('users')
.select('name', 'email')
.where('city', '=', 'Rio de Janeiro')
.limit(5))
results = bridge.execute_builder(query)Vantagens do Query Builder:
- ✅ Type-safe: Menos erros de sintaxe SQL
- ✅ Fluente: Encadeamento de métodos intuitivo
- ✅ Reutilizável: Construa queries dinamicamente
- ✅ Tradução automática: Funciona com todos os bancos
- ✅ Prepared statements: Proteção contra SQL injection
# SQL Padrão
sql = """
CREATE TABLE products (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME
)
"""
# MySQL: AUTO_INCREMENT, TINYINT(1)
# PostgreSQL: SERIAL, BOOLEAN, TIMESTAMP
# Oracle: NUMBER, CLOB, NUMBER(1), TIMESTAMP
# SQL Server: IDENTITY, BIT, DATETIME2# SQL Padrão
sql = "SELECT CURRENT_TIMESTAMP, DATE_ADD(created_at, INTERVAL 7 DAY) FROM orders"
# MySQL: CURRENT_TIMESTAMP, DATE_ADD(created_at, INTERVAL 7 DAY)
# PostgreSQL: CURRENT_TIMESTAMP, created_at + INTERVAL '7 days'
# Oracle: SYSTIMESTAMP, created_at + INTERVAL '7' DAY
# SQL Server: GETDATE(), DATEADD(day, 7, created_at)# SQL Padrão
sql = "SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20"
# MySQL/PostgreSQL/SQLite: LIMIT 10 OFFSET 20
# SQL Server: OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
# Oracle: OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY# SQL Padrão
sql = "SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users"
# MySQL: CONCAT(first_name, ' ', last_name)
# PostgreSQL: first_name || ' ' || last_name
# SQL Server: first_name + ' ' + last_name
# Oracle: first_name || ' ' || last_name# SQL Padrão - Suportado nativamente em todos os bancos modernos
sql = """
WITH dept_avg AS (
SELECT department, AVG(salary) as avg_salary
FROM employees
GROUP BY department
)
SELECT e.name, e.salary, d.avg_salary
FROM employees e
JOIN dept_avg d ON e.department = d.department
"""
bridge.execute(sql)
# Funciona em: MySQL 8.0+, PostgreSQL 8.4+, Oracle 9i+, SQL Server 2005+, DB2, SQLite 3.8.3+# SQL Padrão - Suportado nativamente
sql = """
SELECT
name,
salary,
department,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as rank,
AVG(salary) OVER (PARTITION BY department) as dept_avg
FROM employees
"""
bridge.execute(sql)
# Funciona em: MySQL 8.0+, PostgreSQL 8.4+, Oracle 8.1.6+, SQL Server 2005+, SQLite 3.25.0+bridge = SQLBridge(connection, dialect='auto')Parâmetros:
connection: Conexão DB-API 2.0dialect: 'auto', 'mysql', 'postgresql', 'oracle', 'sqlserver', 'db2', 'informix', 'sqlite'
Métodos:
# Executar SQL traduzido
bridge.execute(sql, params=None)
# Obter SQL traduzido sem executar
translated_sql = bridge.translate(sql)
# Executar query e retornar resultados
results = bridge.query(sql, params=None)
# Executar múltiplos statements
bridge.execute_many(sql_list)bridge = SQLBridge(conn, debug=True)
bridge.execute(sql)
# Imprime: [SQLBridge] Original: SELECT ...
# Imprime: [SQLBridge] Translated: SELECT ...from sqlbridge.dialects import MySQLDialect, PostgreSQLDialect
mysql_dialect = MySQLDialect()
pg_dialect = PostgreSQLDialect()
# Traduzir de MySQL para PostgreSQL
mysql_sql = "SELECT * FROM users LIMIT 10"
standard_sql = mysql_dialect.to_standard(mysql_sql)
pg_sql = pg_dialect.from_standard(standard_sql)from sqlbridge import detect_dialect
dialect = detect_dialect(connection)
print(f"Banco detectado: {dialect}")SQLBridge inclui um CLI poderoso para traduzir scripts SQL:
# Traduzir arquivo SQL
sqlbridge translate -i script.sql -o output.sql -t postgresql
# Traduzir e imprimir no terminal
sqlbridge translate -i script.sql -t mysql
# Traduzir do stdin
echo "SELECT * FROM users LIMIT 10" | sqlbridge translate -t oracle
# Listar dialetos suportados
sqlbridge list
# Ver exemplos
sqlbridge examples# Converter script MySQL para PostgreSQL
sqlbridge translate -i mysql_schema.sql -o postgres_schema.sql -t postgresql
# Comparar traduções entre bancos
sqlbridge translate -i script.sql -t mysql > mysql.sql
sqlbridge translate -i script.sql -t postgresql > postgresql.sql
diff mysql.sql postgresql.sql
# Pipeline com outros comandos
cat migration.sql | sqlbridge translate -t sqlserver | ssh server "psql -f -"# Instalar dependências de desenvolvimento
pip install -e ".[dev]"
# Rodar testes
pytest tests/
# Cobertura
pytest --cov=sqlbridge tests/| Feature | SQLBridge | SQLAlchemy | Django ORM | Peewee | PyDAL | Records |
|---|---|---|---|---|---|---|
| SQL Nativo | ✅ | ❌ | ❌ | ✅ | ||
| Tradução Automática | ✅ | ❌ | ❌ | ❌ | ❌ | |
| Zero Dependências | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| CLI | ✅ | ❌ | ✅ Manage | ❌ | ❌ | ❌ |
| ORM | ❌ | ✅ Completo | ✅ Completo | ✅ Leve | ✅ | ❌ |
| Curva de Aprendizado | ⭐ Baixa | ⭐⭐⭐⭐⭐ Muito Alta | ⭐⭐⭐ Média | ⭐⭐ Baixa | ⭐⭐⭐ Média | ⭐ Baixa |
| Migrations | 🚧 Em dev | ✅ Alembic | ✅ Integrado | ✅ | ✅ Auto | ❌ |
| CTEs | ✅ | ✅ | ✅ | ✅ | ✅ | |
| Window Functions | ✅ | ✅ | ✅ | ✅ | ✅ | |
| Tamanho | ~3.5k LOC | ~100k+ LOC | ~50k+ LOC | ~10k LOC | ~15k LOC | ~1k LOC |
| Multi-Banco | ✅ 7 bancos | ✅ | ✅ | ✅ | ✅ | ✅ |
| Standalone | ✅ | ✅ | ❌ Requer Django | ✅ | ✅ | ✅ |
- Você prefere escrever SQL nativo
- Precisa suportar múltiplos bancos sem reescrever código
- Quer tradução automática de SQL
- Precisa migrar entre bancos de dados
- Quer uma solução leve (zero dependências)
- Precisa de CLI para traduzir scripts
- Valoriza simplicidade e controle total
- Precisa de um ORM completo e robusto
- Projeto grande e complexo
- Precisa de migrations avançadas (Alembic)
- Quer mapeamento objeto-relacional
- Já conhece a biblioteca
- Está usando Django framework
- Precisa de admin interface
- Quer migrations integradas
- Projeto web completo
- Quer um ORM simples e leve
- Projeto pequeno/médio
- Não quer a complexidade do SQLAlchemy
Criar tabela em múltiplos bancos:
# SQLBridge - Mesmo código funciona em qualquer banco
from sqlbridge import SQLBridge
bridge = SQLBridge(connection) # MySQL, PostgreSQL, Oracle, etc.
bridge.execute("""
CREATE TABLE users (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
is_active BOOLEAN DEFAULT TRUE
)
""")
# Traduz automaticamente:
# MySQL: AUTO_INCREMENT, TINYINT(1)
# PostgreSQL: SERIAL, BOOLEAN
# Oracle: GENERATED AS IDENTITY, NUMBER(1)
# SQL Server: IDENTITY(1,1), BIT# SQLAlchemy - Precisa definir classes
from sqlalchemy import Column, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(100))
is_active = Column(Boolean, default=True)
Base.metadata.create_all(engine)Inserção de 10.000 registros (benchmark típico):
| Biblioteca | Tempo | Overhead |
|---|---|---|
| SQLBridge | ~2.5s | Mínimo |
| SQLAlchemy Core | ~2.3s | Baixo |
| Peewee | ~3.0s | Baixo |
| SQLAlchemy ORM | ~8.5s | Alto |
| Django ORM | ~9.0s | Alto |
SQLBridge oferece performance próxima ao SQL puro, sem overhead de ORM.
SQLBridge: "Escreva SQL padrão uma vez, execute em qualquer banco de dados"
SQLAlchemy: "Python classes para representar tabelas"
Django ORM: "ORM integrado ao framework"
SQLBridge complementa, não substitui outras bibliotecas. É uma ferramenta especializada em tradução SQL transparente.
📖 Comparação detalhada: Veja COMPARISON.md para análise completa.
R: Sim! Você precisa criar a conexão com o banco específico (MySQL, PostgreSQL, etc.). O SQLBridge detecta automaticamente o dialeto a partir dessa conexão.
# Você escolhe e conecta ao banco
import psycopg2
conn = psycopg2.connect("postgresql://localhost/mydb")
# SQLBridge detecta automaticamente que é PostgreSQL
bridge = SQLBridge(conn)R: Não! SQLBridge trabalha em cima dos drivers nativos (psycopg2, mysql-connector, etc.). Você ainda precisa:
- Instalar o driver do banco (
pip install psycopg2) - Criar a conexão com o driver
- Passar a conexão para o SQLBridge
R: O mesmo código SQL funciona em qualquer banco:
# Este SQL funciona em MySQL, PostgreSQL, Oracle, SQL Server, etc.
sql = "CREATE TABLE users (id INTEGER AUTO_INCREMENT PRIMARY KEY)"
# MySQL: id INTEGER AUTO_INCREMENT PRIMARY KEY
# PostgreSQL: id SERIAL PRIMARY KEY
# Oracle: id NUMBER GENERATED AS IDENTITY PRIMARY KEY
# SQL Server: id INTEGER IDENTITY(1,1) PRIMARY KEYR: Não! Apenas mude a conexão:
# Desenvolvimento: SQLite
conn = sqlite3.connect('dev.db')
# Produção: PostgreSQL
conn = psycopg2.connect('postgresql://...')
# O resto do código permanece IDÊNTICO!
bridge = SQLBridge(conn)
bridge.execute(sql) # Mesmo SQL, tradução automáticaR: Sim! SQLBridge é complementar. Use para:
- Migrations entre bancos
- Scripts SQL diretos
- Queries complexas
- Quando você prefere SQL nativo
R: Sim!
# Detecção automática (recomendado)
bridge = SQLBridge(conn)
# Forçar dialeto específico
bridge = SQLBridge(conn, dialect='postgresql')R: Versões modernas de cada banco:
- MySQL: 5.7+ (CTEs requerem 8.0+)
- PostgreSQL: 9.0+ (CTEs desde 8.4+)
- Oracle: 11g+ (CTEs desde 9i+)
- SQL Server: 2012+ (CTEs desde 2005+)
- DB2: 9.5+
- Informix: 11.50+
- SQLite: 3.8+ (Window Functions desde 3.25+)
- Suporte básico para 7 bancos de dados
- Tradução de tipos de dados
- Tradução de funções comuns
- Suporte a CTEs (Common Table Expressions)
- Suporte a Window Functions
- CLI para tradução de scripts SQL
- Tradução de stored procedures
- Plugin para IDEs
- Query builder fluente
- Schema migrations automáticas
Contribuições são bem-vindas! Por favor:
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - Push para a branch (
git push origin feature/AmazingFeature) - Abra um Pull Request
MIT License - veja LICENSE para detalhes.
Criado com ❤️ para simplificar o desenvolvimento multi-banco de dados.
Inspirado por SQLAlchemy, mas focado em simplicidade e transparência.