pyEasyMatrixDb 0.1.0__tar.gz

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,248 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyEasyMatrixDb
3
+ Version: 0.1.0
4
+ Summary: Easiest way to search and update a database using matrix like queries
5
+ Author-email: Ricardo Nazar Rodrigues <ricardo@toxt.com.br>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: sqlalchemy>=2.0
9
+
10
+ # pyEasyDb
11
+
12
+ Biblioteca Python para consultar e modificar bancos de dados usando **matrizes bidimensionais** como interface.
13
+ Abstrai SELECT, INSERT, UPDATE e DELETE via SQLAlchemy Core — funciona com qualquer banco suportado (SQLite, PostgreSQL, MySQL, etc.).
14
+
15
+ ## Instalação
16
+
17
+ ```bash
18
+ pip install pyeasymatrixdb
19
+ ```
20
+
21
+ ## GitHub
22
+
23
+ https://github.com/RicNazar/toxt-p10_dbdriver
24
+
25
+ ## Início Rápido
26
+
27
+ ```pythons
28
+ from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ForeignKey
29
+
30
+ # Cria uma engine em memória
31
+ engine = create_engine("sqlite+pysqlite:///:memory:")
32
+ metadata = MetaData()
33
+
34
+ users = Table("users", metadata,
35
+ Column("id", Integer, primary_key=True),
36
+ Column("name", String(100), nullable=False),
37
+ Column("email", String(150), nullable=False),
38
+ )
39
+
40
+ orders = Table("orders", metadata,
41
+ Column("id", Integer, primary_key=True),
42
+ Column("user_id", ForeignKey("users.id"), nullable=False),
43
+ Column("product", String(100), nullable=False),
44
+ )
45
+
46
+ # Cria as tabelas caso não existam
47
+ metadata.create_all(engine)
48
+
49
+ from pyeasydb import DbDriver
50
+ db = DbDriver(metadata, engine)
51
+ ```
52
+
53
+ ## Funcionalidades
54
+
55
+ ### 1. SQL puro — `execute()` / `execute_stmt()`
56
+
57
+ ```python
58
+ # SQL como texto
59
+ resultado = db.execute("SELECT id, name FROM users ORDER BY id")
60
+ # → [["__result__", "__result__"], ["id", "name"], [1, "Ana"], [2, "Bruno"]]
61
+
62
+ # Statement SQLAlchemy
63
+ from sqlalchemy import select
64
+ stmt = select(users.c.id, users.c.name).where(users.c.id >= 2)
65
+ resultado = db.execute_stmt(stmt)
66
+ ```
67
+
68
+ Comandos sem retorno de linhas devolvem `[["__meta__"], ["rowcount"], [n]]`.
69
+
70
+ ---
71
+
72
+ ### 2. Pesquisa — `db.Pesquisar`
73
+
74
+ #### Pesquisa simples
75
+
76
+ ```python
77
+ resultado = (
78
+ db.Pesquisar
79
+ .define_header([
80
+ ["users", "users"],
81
+ ["id", "name"],
82
+ ])
83
+ .search()
84
+ )
85
+ # → [["users", "users"], ["id", "name"], [1, "Ana"], [2, "Bruno"], ...]
86
+ ```
87
+
88
+ #### Pesquisa com JOIN + filtro
89
+
90
+ ```python
91
+ resultado = (
92
+ db.Pesquisar
93
+ .define_header([
94
+ ["users", "orders", "orders"],
95
+ ["name", "product", "status"],
96
+ ])
97
+ .define_relationships([
98
+ ["orders", "users", "user_id", "id", 1], # INNER JOIN
99
+ ])
100
+ .define_filter([
101
+ ["orders"],
102
+ ["status"],
103
+ ["OPEN"],
104
+ ])
105
+ .search()
106
+ )
107
+ ```
108
+
109
+ #### Filtro com OR (múltiplas linhas)
110
+
111
+ ```python
112
+ resultado = (
113
+ db.Pesquisar
114
+ .define_header([["users", "users"], ["id", "name"]])
115
+ .define_filter([
116
+ ["users"],
117
+ ["name"],
118
+ ["Ana"], # OR
119
+ ["Carla"],
120
+ ])
121
+ .search()
122
+ )
123
+ ```
124
+
125
+ #### Filtro com operadores
126
+
127
+ ```python
128
+ .define_filter([
129
+ ["users"],
130
+ ["id"],
131
+ [(">=", 2)], # operadores: !=, >, >=, <, <=, like
132
+ ])
133
+ ```
134
+
135
+ #### Pesquisa completa (todas as colunas)
136
+
137
+ ```python
138
+ resultado = db.Pesquisar.define_header(header).search(complete=True, default=None)
139
+ # Expande a saída para todas as colunas das tabelas envolvidas.
140
+ # Colunas ausentes são preenchidas com o valor de `default`.
141
+ ```
142
+
143
+ ---
144
+
145
+ ### 3. Atualização — `db.Atualizar`
146
+
147
+ A coluna `MD` (última) controla a operação por linha:
148
+
149
+ - `"U"` / `"A"` → Upsert (UPDATE se PK existe ou exclusivo Filtro, INSERT caso contrário)
150
+ - `"D"` → DELETE (exige PK ou exclusifi Filtro)
151
+
152
+ #### Upsert (update + insert)
153
+
154
+ ```python
155
+ resultado = (
156
+ db.Atualizar
157
+ .define_data([
158
+ ["users", "users", "users", "users"],
159
+ ["id", "name", "email", "MD" ],
160
+ [1, "Ana R.","ana@x.com", "U" ], # atualiza id=1
161
+ [5, "Novo", "novo@x.com","U" ], # insere id=5
162
+ ])
163
+ .update()
164
+ )
165
+ ```
166
+
167
+ #### Delete
168
+
169
+ ```python
170
+ resultado = (
171
+ db.Atualizar
172
+ .define_data([
173
+ ["orders", "orders", "orders"],
174
+ ["id", "product", "MD" ],
175
+ [101, "Mouse", "D" ],
176
+ ])
177
+ .update()
178
+ )
179
+ ```
180
+
181
+ #### Atualização com filtro extra
182
+
183
+ ```python
184
+ resultado = (
185
+ db.Atualizar
186
+ .define_data([
187
+ ["orders", "orders", "orders", "orders"],
188
+ ["id", "user_id","status", "MD" ],
189
+ [100, 1, "CLOSED", "U" ],
190
+ ])
191
+ .define_filter([
192
+ ["orders"],
193
+ ["status"],
194
+ ["OPEN"], # só atualiza se status = "OPEN"
195
+ ])
196
+ .update()
197
+ )
198
+ ```
199
+
200
+ #### Retorno completo
201
+
202
+ ```python
203
+ resultado = db.Atualizar.define_data(data).update(complete=True, default="<vazio>")
204
+ # Expande a saída para todas as colunas das tabelas, preenchendo ausentes com o default.
205
+ ```
206
+
207
+ ---
208
+
209
+ ### 4. Encadeamento (fluent API)
210
+
211
+ Todos os métodos `define_*` retornam `self`, permitindo encadeamento:
212
+
213
+ ```python
214
+ db.Pesquisar.define_header(h).define_relationships(r).define_filter(f).search()
215
+ db.Atualizar.define_data(d).define_filter(f).update()
216
+ ```
217
+
218
+ ### 5. Reset automático
219
+
220
+ Por padrão, `search()` e `update()` executam `reset()` após a operação, limpando header/filter/data para a próxima chamada. Passe `reset=False` para manter o estado.
221
+
222
+ ---
223
+
224
+ ## Formato das Matrizes
225
+
226
+ | Modelo | Linhas | Descrição |
227
+ | ----------------- | ------ | --------------------------------------------------------------------- |
228
+ | **header** | 2 | `[tabelas, colunas]` — define colunas do SELECT |
229
+ | **filter** | ≥ 3 | `[tabelas, colunas, valores...]` — AND entre colunas, OR entre linhas |
230
+ | **data** | ≥ 3 | `[tabelas, colunas, valores...]` — última coluna = `"MD"` |
231
+ | **relationships** | N | `[[tabelaA, tabelaB, colA, colB, inner?], ...]` |
232
+
233
+ ## Estrutura do Projeto
234
+
235
+ ```
236
+ app/
237
+ DbDriver/
238
+ DbDriver.py — Classe principal (execute, execute_stmt)
239
+ subclasses/
240
+ DbDriverCore.py — Classe base (reset, define_filter, define_relationships)
241
+ DbDriverSearch.py — Pesquisa (define_header, search)
242
+ DbDriverUpdate.py — Escrita (define_data, update)
243
+ DbDriverUtils.py — Utilitários estáticos (builders, validações)
244
+ ```
245
+
246
+ ## Licença
247
+
248
+ Consulte o arquivo de licença do repositório.
@@ -0,0 +1,239 @@
1
+ # pyEasyDb
2
+
3
+ Biblioteca Python para consultar e modificar bancos de dados usando **matrizes bidimensionais** como interface.
4
+ Abstrai SELECT, INSERT, UPDATE e DELETE via SQLAlchemy Core — funciona com qualquer banco suportado (SQLite, PostgreSQL, MySQL, etc.).
5
+
6
+ ## Instalação
7
+
8
+ ```bash
9
+ pip install pyeasymatrixdb
10
+ ```
11
+
12
+ ## GitHub
13
+
14
+ https://github.com/RicNazar/toxt-p10_dbdriver
15
+
16
+ ## Início Rápido
17
+
18
+ ```pythons
19
+ from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ForeignKey
20
+
21
+ # Cria uma engine em memória
22
+ engine = create_engine("sqlite+pysqlite:///:memory:")
23
+ metadata = MetaData()
24
+
25
+ users = Table("users", metadata,
26
+ Column("id", Integer, primary_key=True),
27
+ Column("name", String(100), nullable=False),
28
+ Column("email", String(150), nullable=False),
29
+ )
30
+
31
+ orders = Table("orders", metadata,
32
+ Column("id", Integer, primary_key=True),
33
+ Column("user_id", ForeignKey("users.id"), nullable=False),
34
+ Column("product", String(100), nullable=False),
35
+ )
36
+
37
+ # Cria as tabelas caso não existam
38
+ metadata.create_all(engine)
39
+
40
+ from pyeasydb import DbDriver
41
+ db = DbDriver(metadata, engine)
42
+ ```
43
+
44
+ ## Funcionalidades
45
+
46
+ ### 1. SQL puro — `execute()` / `execute_stmt()`
47
+
48
+ ```python
49
+ # SQL como texto
50
+ resultado = db.execute("SELECT id, name FROM users ORDER BY id")
51
+ # → [["__result__", "__result__"], ["id", "name"], [1, "Ana"], [2, "Bruno"]]
52
+
53
+ # Statement SQLAlchemy
54
+ from sqlalchemy import select
55
+ stmt = select(users.c.id, users.c.name).where(users.c.id >= 2)
56
+ resultado = db.execute_stmt(stmt)
57
+ ```
58
+
59
+ Comandos sem retorno de linhas devolvem `[["__meta__"], ["rowcount"], [n]]`.
60
+
61
+ ---
62
+
63
+ ### 2. Pesquisa — `db.Pesquisar`
64
+
65
+ #### Pesquisa simples
66
+
67
+ ```python
68
+ resultado = (
69
+ db.Pesquisar
70
+ .define_header([
71
+ ["users", "users"],
72
+ ["id", "name"],
73
+ ])
74
+ .search()
75
+ )
76
+ # → [["users", "users"], ["id", "name"], [1, "Ana"], [2, "Bruno"], ...]
77
+ ```
78
+
79
+ #### Pesquisa com JOIN + filtro
80
+
81
+ ```python
82
+ resultado = (
83
+ db.Pesquisar
84
+ .define_header([
85
+ ["users", "orders", "orders"],
86
+ ["name", "product", "status"],
87
+ ])
88
+ .define_relationships([
89
+ ["orders", "users", "user_id", "id", 1], # INNER JOIN
90
+ ])
91
+ .define_filter([
92
+ ["orders"],
93
+ ["status"],
94
+ ["OPEN"],
95
+ ])
96
+ .search()
97
+ )
98
+ ```
99
+
100
+ #### Filtro com OR (múltiplas linhas)
101
+
102
+ ```python
103
+ resultado = (
104
+ db.Pesquisar
105
+ .define_header([["users", "users"], ["id", "name"]])
106
+ .define_filter([
107
+ ["users"],
108
+ ["name"],
109
+ ["Ana"], # OR
110
+ ["Carla"],
111
+ ])
112
+ .search()
113
+ )
114
+ ```
115
+
116
+ #### Filtro com operadores
117
+
118
+ ```python
119
+ .define_filter([
120
+ ["users"],
121
+ ["id"],
122
+ [(">=", 2)], # operadores: !=, >, >=, <, <=, like
123
+ ])
124
+ ```
125
+
126
+ #### Pesquisa completa (todas as colunas)
127
+
128
+ ```python
129
+ resultado = db.Pesquisar.define_header(header).search(complete=True, default=None)
130
+ # Expande a saída para todas as colunas das tabelas envolvidas.
131
+ # Colunas ausentes são preenchidas com o valor de `default`.
132
+ ```
133
+
134
+ ---
135
+
136
+ ### 3. Atualização — `db.Atualizar`
137
+
138
+ A coluna `MD` (última) controla a operação por linha:
139
+
140
+ - `"U"` / `"A"` → Upsert (UPDATE se PK existe ou exclusivo Filtro, INSERT caso contrário)
141
+ - `"D"` → DELETE (exige PK ou exclusifi Filtro)
142
+
143
+ #### Upsert (update + insert)
144
+
145
+ ```python
146
+ resultado = (
147
+ db.Atualizar
148
+ .define_data([
149
+ ["users", "users", "users", "users"],
150
+ ["id", "name", "email", "MD" ],
151
+ [1, "Ana R.","ana@x.com", "U" ], # atualiza id=1
152
+ [5, "Novo", "novo@x.com","U" ], # insere id=5
153
+ ])
154
+ .update()
155
+ )
156
+ ```
157
+
158
+ #### Delete
159
+
160
+ ```python
161
+ resultado = (
162
+ db.Atualizar
163
+ .define_data([
164
+ ["orders", "orders", "orders"],
165
+ ["id", "product", "MD" ],
166
+ [101, "Mouse", "D" ],
167
+ ])
168
+ .update()
169
+ )
170
+ ```
171
+
172
+ #### Atualização com filtro extra
173
+
174
+ ```python
175
+ resultado = (
176
+ db.Atualizar
177
+ .define_data([
178
+ ["orders", "orders", "orders", "orders"],
179
+ ["id", "user_id","status", "MD" ],
180
+ [100, 1, "CLOSED", "U" ],
181
+ ])
182
+ .define_filter([
183
+ ["orders"],
184
+ ["status"],
185
+ ["OPEN"], # só atualiza se status = "OPEN"
186
+ ])
187
+ .update()
188
+ )
189
+ ```
190
+
191
+ #### Retorno completo
192
+
193
+ ```python
194
+ resultado = db.Atualizar.define_data(data).update(complete=True, default="<vazio>")
195
+ # Expande a saída para todas as colunas das tabelas, preenchendo ausentes com o default.
196
+ ```
197
+
198
+ ---
199
+
200
+ ### 4. Encadeamento (fluent API)
201
+
202
+ Todos os métodos `define_*` retornam `self`, permitindo encadeamento:
203
+
204
+ ```python
205
+ db.Pesquisar.define_header(h).define_relationships(r).define_filter(f).search()
206
+ db.Atualizar.define_data(d).define_filter(f).update()
207
+ ```
208
+
209
+ ### 5. Reset automático
210
+
211
+ Por padrão, `search()` e `update()` executam `reset()` após a operação, limpando header/filter/data para a próxima chamada. Passe `reset=False` para manter o estado.
212
+
213
+ ---
214
+
215
+ ## Formato das Matrizes
216
+
217
+ | Modelo | Linhas | Descrição |
218
+ | ----------------- | ------ | --------------------------------------------------------------------- |
219
+ | **header** | 2 | `[tabelas, colunas]` — define colunas do SELECT |
220
+ | **filter** | ≥ 3 | `[tabelas, colunas, valores...]` — AND entre colunas, OR entre linhas |
221
+ | **data** | ≥ 3 | `[tabelas, colunas, valores...]` — última coluna = `"MD"` |
222
+ | **relationships** | N | `[[tabelaA, tabelaB, colA, colB, inner?], ...]` |
223
+
224
+ ## Estrutura do Projeto
225
+
226
+ ```
227
+ app/
228
+ DbDriver/
229
+ DbDriver.py — Classe principal (execute, execute_stmt)
230
+ subclasses/
231
+ DbDriverCore.py — Classe base (reset, define_filter, define_relationships)
232
+ DbDriverSearch.py — Pesquisa (define_header, search)
233
+ DbDriverUpdate.py — Escrita (define_data, update)
234
+ DbDriverUtils.py — Utilitários estáticos (builders, validações)
235
+ ```
236
+
237
+ ## Licença
238
+
239
+ Consulte o arquivo de licença do repositório.
@@ -0,0 +1,17 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pyEasyMatrixDb"
7
+ version = "0.1.0"
8
+ description = "Easiest way to search and update a database using matrix like queries"
9
+ requires-python = ">=3.10"
10
+ dependencies = ["sqlalchemy>=2.0"]
11
+ authors = [
12
+ { name="Ricardo Nazar Rodrigues", email="ricardo@toxt.com.br" }
13
+ ]
14
+ readme = "README.md"
15
+
16
+ [tool.setuptools.packages.find]
17
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+