dbbridgekit 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: dbbridgekit
3
+ Version: 0.1.0
4
+ Summary: Plataforma genérica de conversão/análise/migração entre bancos de dados via Intermediate Representation (IR) canônica — SQLite, PostgreSQL, MySQL (em progresso), SQL Server (planejado).
5
+ Author-email: Otavio R Santana <tvostrodrigues8@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/tvost2/dbbridge
8
+ Project-URL: Repository, https://github.com/tvost2/dbbridge
9
+ Project-URL: Issues, https://github.com/tvost2/dbbridge/issues
10
+ Project-URL: Documentation, https://github.com/tvost2/dbbridge/blob/main/docs/guide.md
11
+ Project-URL: Changelog, https://github.com/tvost2/dbbridge/blob/main/CHANGELOG.md
12
+ Keywords: sql,sqlite,postgresql,mysql,migration,ir,database
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Database
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: psycopg[binary]>=3.1
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
32
+ Requires-Dist: ruff>=0.6; extra == "dev"
33
+ Requires-Dist: build>=1.0; extra == "dev"
34
+ Requires-Dist: twine>=5.0; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # DBBridge
38
+
39
+ Plataforma genérica de conversão, análise e migração entre bancos de dados, baseada numa
40
+ **Intermediate Representation (IR)** canônica — não um conversor pareado por combinação de bancos.
41
+
42
+ ```txt
43
+ Banco origem → Parser do dialeto origem → IR canônica → Renderer do dialeto destino → Banco destino
44
+ ```
45
+
46
+ Evolução do [PostgresModel](../postgresmodel) generalizada: em vez de assumir SQLite→PostgreSQL
47
+ sempre, qualquer par de dialetos suportados passa pelo mesmo pipeline.
48
+
49
+ ## Status (Fase 1)
50
+
51
+ | Dialeto | Parser | Renderer |
52
+ |---|---|---|
53
+ | SQLite | ✅ | ✅ |
54
+ | PostgreSQL | ✅ | ✅ |
55
+ | MySQL | estrutura registrada (Fase 2) | estrutura registrada (Fase 2) |
56
+ | SQL Server | estrutura registrada (Fase 5) | estrutura registrada (Fase 5) |
57
+
58
+ `dbbridge.dialects.mysql`/`sqlserver` já registram um dialeto "conhecido, ainda não implementado" —
59
+ `dbbridge dialects` lista os dois, e chamar `.parse()`/`.render_schema()` neles levanta
60
+ `NotImplementedError` com a fase planejada, em vez de um erro genérico de dialeto desconhecido.
61
+
62
+ 167 testes, 99% de cobertura (`pytest --cov=dbbridge`). Os poucos pontos não cobertos são código
63
+ genuinamente inalcançável (stubs de método abstrato, guard `if __name__ == "__main__"`) — ver
64
+ [docs/guide.md](docs/guide.md#cobertura-de-testes).
65
+
66
+ ## Instalação
67
+
68
+ ```bash
69
+ pip install -e .
70
+ # ou, pra rodar contra PostgreSQL de verdade:
71
+ pip install -e ".[dev]"
72
+ ```
73
+
74
+ ## Uso rápido
75
+
76
+ ### Traduzir um schema
77
+
78
+ ```bash
79
+ dbbridge translate --from sqlite --to postgres schema.sql
80
+ ```
81
+
82
+ Casos que o parser/renderer não reconhecem com segurança viram `REVIEW_REQUIRED` no stderr — nunca
83
+ uma tradução inventada.
84
+
85
+ ### Escanear um projeto Python
86
+
87
+ ```bash
88
+ dbbridge scan --from sqlite --to postgres ./meu_projeto
89
+ ```
90
+
91
+ Encontra `execute()`/`executemany()` com SQL potencialmente incompatível entre os dois dialetos:
92
+ placeholders (`?` vs `%s`), `sqlite_master`, `PRAGMA`, `INSERT OR IGNORE`/`OR REPLACE`,
93
+ case-sensitivity de `LIKE`, autoincrement, e mais.
94
+
95
+ ### Migrar código-fonte automaticamente
96
+
97
+ ```bash
98
+ dbbridge patch --from sqlite --to postgres ./meu_projeto # dry-run, mostra o plano
99
+ dbbridge apply --from sqlite --to postgres ./meu_projeto # aplica com backup automático
100
+ dbbridge rollback ./meu_projeto # desfaz, restaura do backup
101
+ ```
102
+
103
+ Reescreve só literais de string simples sem ambiguidade (troca de placeholder). `f-strings`,
104
+ concatenação e casos ambíguos (aspas duplas, `INSERT OR REPLACE`, etc.) nunca são alterados
105
+ automaticamente — viram `REVIEW_REQUIRED`/`SKIPPED_COMPLEX_EXPRESSION` no plano.
106
+
107
+ ### Migrar dados entre bancos de verdade
108
+
109
+ ```bash
110
+ dbbridge migrate-data --from sqlite --to postgres \
111
+ --source-dsn ./app.db --target-dsn "host=localhost dbname=app" --tables users leads
112
+ dbbridge validate --from sqlite --to postgres \
113
+ --source-dsn ./app.db --target-dsn "host=localhost dbname=app" --tables users leads
114
+ ```
115
+
116
+ Copia em lotes, nunca faz `DROP`/`TRUNCATE`, sempre acrescenta. `validate` compara contagens e
117
+ checksum (SHA-256) linha a linha quando a tabela é pequena o bastante.
118
+
119
+ ### Compatibility Mode (código antigo continua rodando)
120
+
121
+ ```python
122
+ from dbbridge import connect
123
+
124
+ db = connect(source_dialect="sqlite", target_dialect="postgres", dsn="host=localhost dbname=app")
125
+ db.execute("SELECT * FROM users WHERE id=?", (1,)) # vira %s por baixo, roda no Postgres de verdade
126
+ ```
127
+
128
+ Permite migrar a aplicação por partes: o código continua escrito na sintaxe de origem enquanto o
129
+ banco de verdade já é o destino.
130
+
131
+ ## Exemplos executáveis
132
+
133
+ ```bash
134
+ python examples/translate_schema.py # traduz um schema via API Python
135
+ python examples/scan_and_patch_project.py # scan -> patch -> apply -> rollback num mini-app
136
+ python examples/compat_mode.py # Compatibility Mode de ponta a ponta
137
+ DBBRIDGE_EXAMPLE_PG_DSN="host=localhost dbname=..." python examples/full_data_migration.py
138
+ ```
139
+
140
+ Todos os quatro rodam de verdade (não são pseudocódigo) — os três primeiros só precisam do SQLite
141
+ da stdlib; o último precisa de um PostgreSQL acessível via a variável de ambiente indicada.
142
+
143
+ ## Arquitetura
144
+
145
+ ```txt
146
+ dbbridge/
147
+ cli.py # scan|report|translate|patch|apply|migrate-data|validate|rollback|doctor|dialects
148
+ core/
149
+ ir.py # Schema, Table, Column, ForeignKey, UniqueConstraint, CheckConstraint, Index, View, Trigger, Enum
150
+ types.py # CanonicalType, Ambiguity
151
+ parser.py / renderer.py # contratos + registry (register_parser/get_parser/available_parsers, idem renderer)
152
+ planner.py # translate(sql, source, target) — o pipeline completo numa função
153
+ dialects/
154
+ sqlite.py, postgres.py # implementados
155
+ mysql.py, sqlserver.py # stubs registrados (NotImplementedError com a fase planejada)
156
+ scanner/scanner.py # AST — encontra SQL arriscado por par de dialetos
157
+ codemod/codemod.py # AST — reescreve só literais simples sem ambiguidade
158
+ migration/
159
+ schema_migration.py # traduz + aplica DDL (aditivo, nunca DROP/TRUNCATE)
160
+ data_migration.py # copia dados em lotes
161
+ validator.py # contagens + checksum
162
+ rollback.py # restaura código a partir de backup
163
+ compat/runtime.py # connect() — Compatibility Mode
164
+ reports/report.py # normaliza qualquer resultado pra texto/JSON
165
+ ```
166
+
167
+ Por que IR em vez de conversores pareados: com N dialetos, um conversor direto por par cresce O(N²)
168
+ e duplica a mesma lógica de tipos/constraints em cada combinação. Com um modelo canônico no meio,
169
+ cada dialeto novo precisa de só 1 parser + 1 renderer (O(N)) pra já converter de/para todos os
170
+ outros já implementados.
171
+
172
+ ## Segurança
173
+
174
+ - Toda alteração de código gera backup antes de escrever, e pode ser revertida via `dbbridge rollback`.
175
+ - Migração de schema/dados é sempre aditiva — nunca `DROP`/`TRUNCATE`/`DELETE`.
176
+ - Casos ambíguos (aspas duplas em literal, `INSERT OR REPLACE`, f-strings, expressões dinâmicas)
177
+ nunca são "adivinhados" — viram `REVIEW_REQUIRED` pra revisão manual.
178
+ - `apply_changes` verifica `ast.parse()` do arquivo resultante antes de considerar sucesso; se o
179
+ resultado tiver `SyntaxError`, reverte sozinho a partir do backup.
180
+
181
+ ## Fases
182
+
183
+ 1. **IR + SQLite ↔ PostgreSQL** — atual, completo: parser/renderer dos dois dialetos, scanner,
184
+ codemod, migração de schema/dados, validação por checksum, rollback, CLI, Compatibility Mode.
185
+ 2. MySQL (parser + renderer reais).
186
+ 3. Codemod genérico validado contra os 3 dialetos.
187
+ 4. Data migration validada nos 4 pares centrais (SQLite/Postgres/MySQL cruzados).
188
+ 5. SQL Server.
189
+ 6. **Fases futuras (levantadas, ainda não priorizadas):** shadow migration (rodar origem e destino
190
+ em paralelo comparando resultados antes do cutover final), query replay (reproduzir tráfego real
191
+ de produção contra o destino como teste de carga/compatibilidade), dashboard web, relatórios em
192
+ HTML/PDF (hoje só texto/JSON via `reports/report.py`), mecanismo de plugin formal pra dialetos
193
+ externos (hoje a extensão já é possível via `register_parser`/`register_renderer` — falta só
194
+ empacotar como plugin instalável separadamente, ex. entry points do Python), e suporte a bancos
195
+ não-relacionais como MongoDB (exigiria uma IR paralela pra documentos/coleções — ver
196
+ [docs/compatibility-matrix.md](docs/compatibility-matrix.md#roadmap-além-do-sql-relacional)).
197
+
198
+ Cada fase só avança depois da anterior validada — ver [docs/guide.md](docs/guide.md) para detalhes
199
+ de arquitetura e extensão pra novos dialetos, [docs/cli-reference.md](docs/cli-reference.md) pra
200
+ todos os comandos, [docs/compatibility-matrix.md](docs/compatibility-matrix.md) pro que já
201
+ funciona vs. planejado, [docs/migration-tutorial.md](docs/migration-tutorial.md) pro passo a passo
202
+ completo, e [docs/production-checklist.md](docs/production-checklist.md) antes de rodar contra
203
+ dados reais.
@@ -0,0 +1,34 @@
1
+ dbbridge/__init__.py,sha256=mqAYHp2tFx35S1_q7h9Rz1TslbUszTuWbfZHaOJ_Fig,1055
2
+ dbbridge/cli.py,sha256=J5J1_FLSy13dyyAJfbm2vDYbaKT7QFT95VsRJpw6CTw,8269
3
+ dbbridge/codemod/__init__.py,sha256=biRfAiFhJP8XxfwlBmyCoUniwzGumL0vGFhxE6VXgSk,212
4
+ dbbridge/codemod/codemod.py,sha256=ocQ1Der4f3w8ODDtMIpYZhsHIy3x3RPx1fGlUDd5H6M,7444
5
+ dbbridge/compat/__init__.py,sha256=gUNC_UnfYKbIw70nFjUKuc9bXiEGmX0vIT0F2hlz0kI,144
6
+ dbbridge/compat/runtime.py,sha256=dzasZz1S1r0kWpkE_1lwMIwkIGAYo3I98OGXl6FD7Ak,6993
7
+ dbbridge/core/__init__.py,sha256=Y1rv3nLtwXhqEXZHS67uc6JxzcH6G_WENJjigX0Fif4,204
8
+ dbbridge/core/ir.py,sha256=4aer_ShsgYcaxzNjgsIKH7EN1BtfLV1jhwO24xY_JO0,3197
9
+ dbbridge/core/parser.py,sha256=x7EgboyXGxvDTsfsZkbDv-j8qqHo52RX4Z4JFgJcA9Q,1723
10
+ dbbridge/core/planner.py,sha256=YLlCOEdLX4_bY_yRPSCb8R52VIVdjorwxpbUdSlT-7Q,1635
11
+ dbbridge/core/renderer.py,sha256=qE3Rw8hfvLWcmn59wRj7KfSK9zmlguPZjpYX5_dXFc4,1615
12
+ dbbridge/core/sql_lex.py,sha256=-2_ecX78srF0khEfewqa-kKg8i8ZXXo_CrXKNDI5tss,2214
13
+ dbbridge/core/types.py,sha256=C8ecH3TIG9LfEdQx07aocOp_EBO8QGTlmLhWtmjVwig,1915
14
+ dbbridge/dialects/__init__.py,sha256=fpvZlp6Ss3xWdqpwy55pNLb4AqH_MpHc71Yxu93KPyA,578
15
+ dbbridge/dialects/_stub.py,sha256=M7ZjZ0WGKKzC5l4Tl1iz9mxaNCDezxlkiDb68xmsHho,1494
16
+ dbbridge/dialects/mysql.py,sha256=rMv_4p69-CEwDT9em_L3VSfHS1Tozszou2Bt3p6p3sk,882
17
+ dbbridge/dialects/postgres.py,sha256=JanJ1-8oLOTtE5RMEVh-9UeYylGWIrnkfLJxjZsQP8M,14715
18
+ dbbridge/dialects/sqlite.py,sha256=8BaFqYB8mBFBkeXOTKjd6TuCpEV06CBdpPWZnEoUUwY,13370
19
+ dbbridge/dialects/sqlserver.py,sha256=5b7lXKcgVaBGz_SfORjxg-zSXC3QTZAqhFdG9oYPw-U,827
20
+ dbbridge/migration/__init__.py,sha256=mIijSHU-YySvK8P2REJjURP2OuFpBp3A9KE878cwmfg,660
21
+ dbbridge/migration/data_migration.py,sha256=b7oc7jZoygo7JlrGdfjBmSH5ARGkyffBQhiU_m81oV0,3081
22
+ dbbridge/migration/rollback.py,sha256=OfFO6m6oYoYZM0DF-R-va9u3xVqvowBWw4ReNvyZrzk,2773
23
+ dbbridge/migration/schema_migration.py,sha256=PwULtiY-yzm4_J_Y1TnGiqYyW2Tf-qfAmKCbjFUMGwE,2563
24
+ dbbridge/migration/validator.py,sha256=0ToAA5I_v_E9MqNldYIlXF-WMp8QX1mosD6aClLkVZU,3533
25
+ dbbridge/reports/__init__.py,sha256=FkbDWy0IoFG9j7j5TfyVHt_ty2kajqml-jOeAwdCCoM,63
26
+ dbbridge/reports/report.py,sha256=DEJgUpp8SAz0ubfWn8T4XJvBAIPACppYIZJF2XYyrUI,2174
27
+ dbbridge/scanner/__init__.py,sha256=jxSHb0B0cc0VsQ1SrbZugnzpBk-rMwlPzrSnI-7hrQk,132
28
+ dbbridge/scanner/scanner.py,sha256=yNX8tJvY7X1kt50ovK_00Rm0CjqdFBPDvVkETqmPN7A,7363
29
+ dbbridgekit-0.1.0.dist-info/licenses/LICENSE,sha256=w420EVFiwiE-sHoWuBWBFU43utsywuNB1j6lxMhixnM,1073
30
+ dbbridgekit-0.1.0.dist-info/METADATA,sha256=F-PCsUyBbicojFNVH5lzu2ZIsY61axC4Y2VaGwjOgCw,9885
31
+ dbbridgekit-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
32
+ dbbridgekit-0.1.0.dist-info/entry_points.txt,sha256=LeXVMCSu5O3QLbE7VsZAMW-9rwkA-cqu5buh5fkNq3A,47
33
+ dbbridgekit-0.1.0.dist-info/top_level.txt,sha256=0lasTC02xVIOZh_nx7IXUjPQuVYr3nx-Vcw3rs9rxYI,9
34
+ dbbridgekit-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dbbridge = dbbridge.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Otavio R Santana
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ dbbridge