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.
- pyeasymatrixdb-0.1.0/PKG-INFO +248 -0
- pyeasymatrixdb-0.1.0/README.md +239 -0
- pyeasymatrixdb-0.1.0/pyproject.toml +17 -0
- pyeasymatrixdb-0.1.0/setup.cfg +4 -0
- pyeasymatrixdb-0.1.0/src/pyEasyMatrixDb.egg-info/PKG-INFO +248 -0
- pyeasymatrixdb-0.1.0/src/pyEasyMatrixDb.egg-info/SOURCES.txt +14 -0
- pyeasymatrixdb-0.1.0/src/pyEasyMatrixDb.egg-info/dependency_links.txt +1 -0
- pyeasymatrixdb-0.1.0/src/pyEasyMatrixDb.egg-info/requires.txt +1 -0
- pyeasymatrixdb-0.1.0/src/pyEasyMatrixDb.egg-info/top_level.txt +1 -0
- pyeasymatrixdb-0.1.0/src/pyeasymatrixdb/DbDriver.py +35 -0
- pyeasymatrixdb-0.1.0/src/pyeasymatrixdb/__init__.py +3 -0
- pyeasymatrixdb-0.1.0/src/pyeasymatrixdb/subclasses/DbDriverCore.py +53 -0
- pyeasymatrixdb-0.1.0/src/pyeasymatrixdb/subclasses/DbDriverSearch.py +61 -0
- pyeasymatrixdb-0.1.0/src/pyeasymatrixdb/subclasses/DbDriverUpdate.py +130 -0
- pyeasymatrixdb-0.1.0/src/pyeasymatrixdb/subclasses/DbDriverUtils.py +417 -0
- pyeasymatrixdb-0.1.0/src/pyeasymatrixdb/subclasses/__init__.py +11 -0
|
@@ -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"]
|