pyflashdb 1.0.1__tar.gz → 1.0.2__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.
- pyflashdb-1.0.2/PKG-INFO +365 -0
- pyflashdb-1.0.2/README.md +333 -0
- pyflashdb-1.0.2/pyflashdb.egg-info/PKG-INFO +365 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/setup.py +5 -2
- pyflashdb-1.0.1/PKG-INFO +0 -34
- pyflashdb-1.0.1/README.md +0 -2
- pyflashdb-1.0.1/pyflashdb.egg-info/PKG-INFO +0 -34
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/__init__.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/adapters/__init__.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/adapters/mongo_adapter.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/adapters/mysql_adapter.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/adapters/postgres_adapter.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/core.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/exceptions.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/filters.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/flash/triggers.py +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/pyflashdb.egg-info/SOURCES.txt +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/pyflashdb.egg-info/dependency_links.txt +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/pyflashdb.egg-info/requires.txt +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/pyflashdb.egg-info/top_level.txt +0 -0
- {pyflashdb-1.0.1 → pyflashdb-1.0.2}/setup.cfg +0 -0
pyflashdb-1.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyflashdb
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: A unified, trigger-aware database interface for MySQL, PostgreSQL, and MongoDB.
|
|
5
|
+
Author: Flash Team
|
|
6
|
+
Keywords: database mysql postgresql mongodb orm crud flash unified
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Topic :: Database
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Provides-Extra: mysql
|
|
15
|
+
Requires-Dist: mysql-connector-python>=8.0; extra == "mysql"
|
|
16
|
+
Provides-Extra: postgres
|
|
17
|
+
Requires-Dist: psycopg2-binary>=2.9; extra == "postgres"
|
|
18
|
+
Provides-Extra: mongodb
|
|
19
|
+
Requires-Dist: pymongo>=4.0; extra == "mongodb"
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
Requires-Dist: mysql-connector-python>=8.0; extra == "all"
|
|
22
|
+
Requires-Dist: psycopg2-binary>=2.9; extra == "all"
|
|
23
|
+
Requires-Dist: pymongo>=4.0; extra == "all"
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: keywords
|
|
29
|
+
Dynamic: provides-extra
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# Flash — Unified Database Interface
|
|
34
|
+
|
|
35
|
+
Flash is a lightweight Python library that gives you one clean API for **MySQL**, **PostgreSQL**, and **MongoDB** — with built-in trigger hooks, no models required.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from flash import FlashDB
|
|
39
|
+
|
|
40
|
+
flash = FlashDB("mysql", config)
|
|
41
|
+
flash.add("users", {"name": "John", "age": 25})
|
|
42
|
+
flash.where("users", {"age": {">": 18}})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 📦 Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install flashdb
|
|
51
|
+
|
|
52
|
+
# With specific driver:
|
|
53
|
+
pip install flashdb[mysql] # MySQL
|
|
54
|
+
pip install flashdb[postgres] # PostgreSQL
|
|
55
|
+
pip install flashdb[mongodb] # MongoDB
|
|
56
|
+
pip install flashdb[all] # All drivers
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🔌 Connection
|
|
62
|
+
|
|
63
|
+
### MySQL
|
|
64
|
+
```python
|
|
65
|
+
from flash import FlashDB
|
|
66
|
+
|
|
67
|
+
flash = FlashDB("mysql", {
|
|
68
|
+
"host": "localhost",
|
|
69
|
+
"port": 3306,
|
|
70
|
+
"user": "root",
|
|
71
|
+
"password": "1234",
|
|
72
|
+
"database": "mydb"
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### PostgreSQL
|
|
77
|
+
```python
|
|
78
|
+
flash = FlashDB("postgres", {
|
|
79
|
+
"host": "localhost",
|
|
80
|
+
"port": 5432,
|
|
81
|
+
"user": "postgres",
|
|
82
|
+
"password": "1234",
|
|
83
|
+
"database": "mydb"
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### MongoDB
|
|
88
|
+
```python
|
|
89
|
+
flash = FlashDB("mongodb", {
|
|
90
|
+
"host": "localhost",
|
|
91
|
+
"port": 27017,
|
|
92
|
+
"database": "mydb"
|
|
93
|
+
# Or use: "uri": "mongodb+srv://..."
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Context Manager
|
|
98
|
+
```python
|
|
99
|
+
with FlashDB("mysql", config) as flash:
|
|
100
|
+
flash.add("users", {"name": "John"})
|
|
101
|
+
# Connection auto-closed
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🧩 CRUD Operations
|
|
107
|
+
|
|
108
|
+
### ➕ Insert
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
# Single record
|
|
112
|
+
flash.add("users", {"name": "Alice", "age": 22})
|
|
113
|
+
|
|
114
|
+
# Bulk insert
|
|
115
|
+
flash.bulk_insert("users", [
|
|
116
|
+
{"name": "Alice", "age": 22},
|
|
117
|
+
{"name": "Bob", "age": 30},
|
|
118
|
+
])
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 📖 Read
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
# All records
|
|
125
|
+
flash.all("users")
|
|
126
|
+
|
|
127
|
+
# With filters
|
|
128
|
+
flash.where("users", {"name": "Alice"})
|
|
129
|
+
flash.where("users", {"age": {">": 18}})
|
|
130
|
+
|
|
131
|
+
# Specific fields
|
|
132
|
+
flash.select("users", fields=["name", "age"])
|
|
133
|
+
|
|
134
|
+
# Combined
|
|
135
|
+
flash.select("users",
|
|
136
|
+
fields=["name", "age"],
|
|
137
|
+
filters={"age": {">": 18}},
|
|
138
|
+
order_by="age",
|
|
139
|
+
limit=10
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Single record
|
|
143
|
+
flash.find_one("users", {"name": "Alice"})
|
|
144
|
+
|
|
145
|
+
# Count
|
|
146
|
+
flash.count("users", {"age": {">": 18}})
|
|
147
|
+
|
|
148
|
+
# Limit
|
|
149
|
+
flash.limit("users", 5)
|
|
150
|
+
|
|
151
|
+
# Paginate
|
|
152
|
+
flash.paginate("users", page=2, size=10)
|
|
153
|
+
# Returns: {"data": [...], "page": 2, "size": 10, "total": 42}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### ✏️ Update
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
flash.update("users", {"name": "Alice"}, {"age": 23})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 🗑️ Delete
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
flash.delete("users", {"name": "Alice"})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 🔍 Filter Operators
|
|
171
|
+
|
|
172
|
+
Flash uses a unified filter syntax that automatically translates to SQL or MongoDB:
|
|
173
|
+
|
|
174
|
+
| Flash Operator | SQL | MongoDB |
|
|
175
|
+
|---------------|-----------|----------|
|
|
176
|
+
| `>` | `>` | `$gt` |
|
|
177
|
+
| `<` | `<` | `$lt` |
|
|
178
|
+
| `>=` | `>=` | `$gte` |
|
|
179
|
+
| `<=` | `<=` | `$lte` |
|
|
180
|
+
| `!=` | `!=` | `$ne` |
|
|
181
|
+
| `in` | `IN` | `$in` |
|
|
182
|
+
| `not in` | `NOT IN` | `$nin` |
|
|
183
|
+
| `like` | `LIKE` | `$regex` |
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
flash.where("users", {"age": {">": 18}})
|
|
187
|
+
flash.where("users", {"role": {"in": ["admin", "mod"]}})
|
|
188
|
+
flash.where("users", {"name": {"like": "Jo%"}})
|
|
189
|
+
flash.where("users", {"score": {">=": 80, "<=": 100}})
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 🔔 Trigger Hooks
|
|
195
|
+
|
|
196
|
+
Flash supports before/after hooks for all operations — even on MongoDB where native triggers don't exist.
|
|
197
|
+
|
|
198
|
+
### Decorator Style
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
@flash.before_insert("users")
|
|
202
|
+
def validate(data):
|
|
203
|
+
if not data.get("name"):
|
|
204
|
+
raise ValueError("Name is required")
|
|
205
|
+
|
|
206
|
+
@flash.after_insert("users")
|
|
207
|
+
def on_created(data, result):
|
|
208
|
+
print(f"New user created with ID: {result}")
|
|
209
|
+
|
|
210
|
+
@flash.before_update("users")
|
|
211
|
+
def log_update(payload):
|
|
212
|
+
print("Updating:", payload["filters"], "->", payload["data"])
|
|
213
|
+
|
|
214
|
+
@flash.after_delete("users")
|
|
215
|
+
def on_deleted(filters, count):
|
|
216
|
+
print(f"Deleted {count} record(s)")
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Programmatic Style
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
def audit_log(data):
|
|
223
|
+
print("Insert:", data)
|
|
224
|
+
|
|
225
|
+
flash.add_hook("before", "insert", "users", audit_log)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Available Hooks
|
|
229
|
+
|
|
230
|
+
| Hook | When it fires |
|
|
231
|
+
|-----------------------------|--------------------------------|
|
|
232
|
+
| `before_insert(table)` | Before `add()` or `bulk_insert()` |
|
|
233
|
+
| `after_insert(table)` | After `add()` or `bulk_insert()` |
|
|
234
|
+
| `before_update(table)` | Before `update()` |
|
|
235
|
+
| `after_update(table)` | After `update()` |
|
|
236
|
+
| `before_delete(table)` | Before `delete()` |
|
|
237
|
+
| `after_delete(table)` | After `delete()` |
|
|
238
|
+
| `before_select(table)` | Before `all()`, `select()`, `where()` |
|
|
239
|
+
| `after_select(table)` | After any read operation |
|
|
240
|
+
|
|
241
|
+
### Manage Hooks
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
flash.list_hooks() # See all registered hooks
|
|
245
|
+
flash.clear_hooks() # Remove all hooks
|
|
246
|
+
flash.clear_hooks("users") # Remove hooks for one table
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 📄 Schema Operations
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
# Create table/collection
|
|
255
|
+
flash.create_table("users", {
|
|
256
|
+
"id": "int",
|
|
257
|
+
"name": "str",
|
|
258
|
+
"email": "str",
|
|
259
|
+
"age": "int",
|
|
260
|
+
"score": "float"
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
# Drop table
|
|
264
|
+
flash.drop_table("users")
|
|
265
|
+
|
|
266
|
+
# Truncate (keep structure, delete data)
|
|
267
|
+
flash.truncate("users")
|
|
268
|
+
|
|
269
|
+
# List tables
|
|
270
|
+
flash.show_tables()
|
|
271
|
+
|
|
272
|
+
# Describe structure
|
|
273
|
+
flash.describe("users")
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Supported Type Strings
|
|
277
|
+
|
|
278
|
+
| Flash Type | MySQL | PostgreSQL |
|
|
279
|
+
|-----------|----------------|----------------|
|
|
280
|
+
| `int` | INT | INTEGER |
|
|
281
|
+
| `str` | VARCHAR(255) | VARCHAR(255) |
|
|
282
|
+
| `text` | TEXT | TEXT |
|
|
283
|
+
| `float` | FLOAT | REAL |
|
|
284
|
+
| `bool` | TINYINT(1) | BOOLEAN |
|
|
285
|
+
| `date` | DATE | DATE |
|
|
286
|
+
| `datetime`| DATETIME | TIMESTAMP |
|
|
287
|
+
| `json` | JSON | JSONB |
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 🔐 Transactions (SQL)
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
flash.begin()
|
|
295
|
+
try:
|
|
296
|
+
flash.add("accounts", {"user": "Alice", "balance": 500})
|
|
297
|
+
flash.update("accounts", {"user": "Bob"}, {"balance": 100})
|
|
298
|
+
flash.commit()
|
|
299
|
+
except Exception:
|
|
300
|
+
flash.rollback()
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 🧰 Raw Queries
|
|
306
|
+
|
|
307
|
+
```python
|
|
308
|
+
# SQL
|
|
309
|
+
flash.raw("SELECT * FROM users WHERE age > %s", [18])
|
|
310
|
+
|
|
311
|
+
# MongoDB (pass raw filter dict)
|
|
312
|
+
flash.raw({"age": {"$gt": 18}}, table="users")
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## 🍃 MongoDB-Specific
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
# Aggregation pipeline
|
|
321
|
+
flash.aggregate("orders", [
|
|
322
|
+
{"$match": {"status": "paid"}},
|
|
323
|
+
{"$group": {"_id": "$user_id", "total": {"$sum": "$amount"}}},
|
|
324
|
+
{"$sort": {"total": -1}}
|
|
325
|
+
])
|
|
326
|
+
|
|
327
|
+
# Create index
|
|
328
|
+
flash.create_index("users", "email", unique=True)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## 🔧 Utilities
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
flash.ping() # True if connection is alive
|
|
337
|
+
flash.close() # Close connection
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## 📁 Project Structure
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
flash/
|
|
346
|
+
├── flash/
|
|
347
|
+
│ ├── __init__.py # Package entry point
|
|
348
|
+
│ ├── core.py # FlashDB main class
|
|
349
|
+
│ ├── filters.py # Filter/query translation
|
|
350
|
+
│ ├── triggers.py # Hook/trigger system
|
|
351
|
+
│ ├── exceptions.py # Custom exceptions
|
|
352
|
+
│ └── adapters/
|
|
353
|
+
│ ├── __init__.py
|
|
354
|
+
│ ├── mysql_adapter.py
|
|
355
|
+
│ ├── postgres_adapter.py
|
|
356
|
+
│ └── mongo_adapter.py
|
|
357
|
+
├── setup.py
|
|
358
|
+
└── README.md
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## 📜 License
|
|
364
|
+
|
|
365
|
+
MIT © Flash Team
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# Flash — Unified Database Interface
|
|
2
|
+
|
|
3
|
+
Flash is a lightweight Python library that gives you one clean API for **MySQL**, **PostgreSQL**, and **MongoDB** — with built-in trigger hooks, no models required.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
from flash import FlashDB
|
|
7
|
+
|
|
8
|
+
flash = FlashDB("mysql", config)
|
|
9
|
+
flash.add("users", {"name": "John", "age": 25})
|
|
10
|
+
flash.where("users", {"age": {">": 18}})
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install flashdb
|
|
19
|
+
|
|
20
|
+
# With specific driver:
|
|
21
|
+
pip install flashdb[mysql] # MySQL
|
|
22
|
+
pip install flashdb[postgres] # PostgreSQL
|
|
23
|
+
pip install flashdb[mongodb] # MongoDB
|
|
24
|
+
pip install flashdb[all] # All drivers
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🔌 Connection
|
|
30
|
+
|
|
31
|
+
### MySQL
|
|
32
|
+
```python
|
|
33
|
+
from flash import FlashDB
|
|
34
|
+
|
|
35
|
+
flash = FlashDB("mysql", {
|
|
36
|
+
"host": "localhost",
|
|
37
|
+
"port": 3306,
|
|
38
|
+
"user": "root",
|
|
39
|
+
"password": "1234",
|
|
40
|
+
"database": "mydb"
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### PostgreSQL
|
|
45
|
+
```python
|
|
46
|
+
flash = FlashDB("postgres", {
|
|
47
|
+
"host": "localhost",
|
|
48
|
+
"port": 5432,
|
|
49
|
+
"user": "postgres",
|
|
50
|
+
"password": "1234",
|
|
51
|
+
"database": "mydb"
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### MongoDB
|
|
56
|
+
```python
|
|
57
|
+
flash = FlashDB("mongodb", {
|
|
58
|
+
"host": "localhost",
|
|
59
|
+
"port": 27017,
|
|
60
|
+
"database": "mydb"
|
|
61
|
+
# Or use: "uri": "mongodb+srv://..."
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Context Manager
|
|
66
|
+
```python
|
|
67
|
+
with FlashDB("mysql", config) as flash:
|
|
68
|
+
flash.add("users", {"name": "John"})
|
|
69
|
+
# Connection auto-closed
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 🧩 CRUD Operations
|
|
75
|
+
|
|
76
|
+
### ➕ Insert
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
# Single record
|
|
80
|
+
flash.add("users", {"name": "Alice", "age": 22})
|
|
81
|
+
|
|
82
|
+
# Bulk insert
|
|
83
|
+
flash.bulk_insert("users", [
|
|
84
|
+
{"name": "Alice", "age": 22},
|
|
85
|
+
{"name": "Bob", "age": 30},
|
|
86
|
+
])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 📖 Read
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# All records
|
|
93
|
+
flash.all("users")
|
|
94
|
+
|
|
95
|
+
# With filters
|
|
96
|
+
flash.where("users", {"name": "Alice"})
|
|
97
|
+
flash.where("users", {"age": {">": 18}})
|
|
98
|
+
|
|
99
|
+
# Specific fields
|
|
100
|
+
flash.select("users", fields=["name", "age"])
|
|
101
|
+
|
|
102
|
+
# Combined
|
|
103
|
+
flash.select("users",
|
|
104
|
+
fields=["name", "age"],
|
|
105
|
+
filters={"age": {">": 18}},
|
|
106
|
+
order_by="age",
|
|
107
|
+
limit=10
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Single record
|
|
111
|
+
flash.find_one("users", {"name": "Alice"})
|
|
112
|
+
|
|
113
|
+
# Count
|
|
114
|
+
flash.count("users", {"age": {">": 18}})
|
|
115
|
+
|
|
116
|
+
# Limit
|
|
117
|
+
flash.limit("users", 5)
|
|
118
|
+
|
|
119
|
+
# Paginate
|
|
120
|
+
flash.paginate("users", page=2, size=10)
|
|
121
|
+
# Returns: {"data": [...], "page": 2, "size": 10, "total": 42}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### ✏️ Update
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
flash.update("users", {"name": "Alice"}, {"age": 23})
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 🗑️ Delete
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
flash.delete("users", {"name": "Alice"})
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 🔍 Filter Operators
|
|
139
|
+
|
|
140
|
+
Flash uses a unified filter syntax that automatically translates to SQL or MongoDB:
|
|
141
|
+
|
|
142
|
+
| Flash Operator | SQL | MongoDB |
|
|
143
|
+
|---------------|-----------|----------|
|
|
144
|
+
| `>` | `>` | `$gt` |
|
|
145
|
+
| `<` | `<` | `$lt` |
|
|
146
|
+
| `>=` | `>=` | `$gte` |
|
|
147
|
+
| `<=` | `<=` | `$lte` |
|
|
148
|
+
| `!=` | `!=` | `$ne` |
|
|
149
|
+
| `in` | `IN` | `$in` |
|
|
150
|
+
| `not in` | `NOT IN` | `$nin` |
|
|
151
|
+
| `like` | `LIKE` | `$regex` |
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
flash.where("users", {"age": {">": 18}})
|
|
155
|
+
flash.where("users", {"role": {"in": ["admin", "mod"]}})
|
|
156
|
+
flash.where("users", {"name": {"like": "Jo%"}})
|
|
157
|
+
flash.where("users", {"score": {">=": 80, "<=": 100}})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 🔔 Trigger Hooks
|
|
163
|
+
|
|
164
|
+
Flash supports before/after hooks for all operations — even on MongoDB where native triggers don't exist.
|
|
165
|
+
|
|
166
|
+
### Decorator Style
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
@flash.before_insert("users")
|
|
170
|
+
def validate(data):
|
|
171
|
+
if not data.get("name"):
|
|
172
|
+
raise ValueError("Name is required")
|
|
173
|
+
|
|
174
|
+
@flash.after_insert("users")
|
|
175
|
+
def on_created(data, result):
|
|
176
|
+
print(f"New user created with ID: {result}")
|
|
177
|
+
|
|
178
|
+
@flash.before_update("users")
|
|
179
|
+
def log_update(payload):
|
|
180
|
+
print("Updating:", payload["filters"], "->", payload["data"])
|
|
181
|
+
|
|
182
|
+
@flash.after_delete("users")
|
|
183
|
+
def on_deleted(filters, count):
|
|
184
|
+
print(f"Deleted {count} record(s)")
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Programmatic Style
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
def audit_log(data):
|
|
191
|
+
print("Insert:", data)
|
|
192
|
+
|
|
193
|
+
flash.add_hook("before", "insert", "users", audit_log)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Available Hooks
|
|
197
|
+
|
|
198
|
+
| Hook | When it fires |
|
|
199
|
+
|-----------------------------|--------------------------------|
|
|
200
|
+
| `before_insert(table)` | Before `add()` or `bulk_insert()` |
|
|
201
|
+
| `after_insert(table)` | After `add()` or `bulk_insert()` |
|
|
202
|
+
| `before_update(table)` | Before `update()` |
|
|
203
|
+
| `after_update(table)` | After `update()` |
|
|
204
|
+
| `before_delete(table)` | Before `delete()` |
|
|
205
|
+
| `after_delete(table)` | After `delete()` |
|
|
206
|
+
| `before_select(table)` | Before `all()`, `select()`, `where()` |
|
|
207
|
+
| `after_select(table)` | After any read operation |
|
|
208
|
+
|
|
209
|
+
### Manage Hooks
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
flash.list_hooks() # See all registered hooks
|
|
213
|
+
flash.clear_hooks() # Remove all hooks
|
|
214
|
+
flash.clear_hooks("users") # Remove hooks for one table
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 📄 Schema Operations
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
# Create table/collection
|
|
223
|
+
flash.create_table("users", {
|
|
224
|
+
"id": "int",
|
|
225
|
+
"name": "str",
|
|
226
|
+
"email": "str",
|
|
227
|
+
"age": "int",
|
|
228
|
+
"score": "float"
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
# Drop table
|
|
232
|
+
flash.drop_table("users")
|
|
233
|
+
|
|
234
|
+
# Truncate (keep structure, delete data)
|
|
235
|
+
flash.truncate("users")
|
|
236
|
+
|
|
237
|
+
# List tables
|
|
238
|
+
flash.show_tables()
|
|
239
|
+
|
|
240
|
+
# Describe structure
|
|
241
|
+
flash.describe("users")
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Supported Type Strings
|
|
245
|
+
|
|
246
|
+
| Flash Type | MySQL | PostgreSQL |
|
|
247
|
+
|-----------|----------------|----------------|
|
|
248
|
+
| `int` | INT | INTEGER |
|
|
249
|
+
| `str` | VARCHAR(255) | VARCHAR(255) |
|
|
250
|
+
| `text` | TEXT | TEXT |
|
|
251
|
+
| `float` | FLOAT | REAL |
|
|
252
|
+
| `bool` | TINYINT(1) | BOOLEAN |
|
|
253
|
+
| `date` | DATE | DATE |
|
|
254
|
+
| `datetime`| DATETIME | TIMESTAMP |
|
|
255
|
+
| `json` | JSON | JSONB |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 🔐 Transactions (SQL)
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
flash.begin()
|
|
263
|
+
try:
|
|
264
|
+
flash.add("accounts", {"user": "Alice", "balance": 500})
|
|
265
|
+
flash.update("accounts", {"user": "Bob"}, {"balance": 100})
|
|
266
|
+
flash.commit()
|
|
267
|
+
except Exception:
|
|
268
|
+
flash.rollback()
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## 🧰 Raw Queries
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
# SQL
|
|
277
|
+
flash.raw("SELECT * FROM users WHERE age > %s", [18])
|
|
278
|
+
|
|
279
|
+
# MongoDB (pass raw filter dict)
|
|
280
|
+
flash.raw({"age": {"$gt": 18}}, table="users")
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## 🍃 MongoDB-Specific
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
# Aggregation pipeline
|
|
289
|
+
flash.aggregate("orders", [
|
|
290
|
+
{"$match": {"status": "paid"}},
|
|
291
|
+
{"$group": {"_id": "$user_id", "total": {"$sum": "$amount"}}},
|
|
292
|
+
{"$sort": {"total": -1}}
|
|
293
|
+
])
|
|
294
|
+
|
|
295
|
+
# Create index
|
|
296
|
+
flash.create_index("users", "email", unique=True)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## 🔧 Utilities
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
flash.ping() # True if connection is alive
|
|
305
|
+
flash.close() # Close connection
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 📁 Project Structure
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
flash/
|
|
314
|
+
├── flash/
|
|
315
|
+
│ ├── __init__.py # Package entry point
|
|
316
|
+
│ ├── core.py # FlashDB main class
|
|
317
|
+
│ ├── filters.py # Filter/query translation
|
|
318
|
+
│ ├── triggers.py # Hook/trigger system
|
|
319
|
+
│ ├── exceptions.py # Custom exceptions
|
|
320
|
+
│ └── adapters/
|
|
321
|
+
│ ├── __init__.py
|
|
322
|
+
│ ├── mysql_adapter.py
|
|
323
|
+
│ ├── postgres_adapter.py
|
|
324
|
+
│ └── mongo_adapter.py
|
|
325
|
+
├── setup.py
|
|
326
|
+
└── README.md
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 📜 License
|
|
332
|
+
|
|
333
|
+
MIT © Flash Team
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyflashdb
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: A unified, trigger-aware database interface for MySQL, PostgreSQL, and MongoDB.
|
|
5
|
+
Author: Flash Team
|
|
6
|
+
Keywords: database mysql postgresql mongodb orm crud flash unified
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Topic :: Database
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Provides-Extra: mysql
|
|
15
|
+
Requires-Dist: mysql-connector-python>=8.0; extra == "mysql"
|
|
16
|
+
Provides-Extra: postgres
|
|
17
|
+
Requires-Dist: psycopg2-binary>=2.9; extra == "postgres"
|
|
18
|
+
Provides-Extra: mongodb
|
|
19
|
+
Requires-Dist: pymongo>=4.0; extra == "mongodb"
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
Requires-Dist: mysql-connector-python>=8.0; extra == "all"
|
|
22
|
+
Requires-Dist: psycopg2-binary>=2.9; extra == "all"
|
|
23
|
+
Requires-Dist: pymongo>=4.0; extra == "all"
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: keywords
|
|
29
|
+
Dynamic: provides-extra
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# Flash — Unified Database Interface
|
|
34
|
+
|
|
35
|
+
Flash is a lightweight Python library that gives you one clean API for **MySQL**, **PostgreSQL**, and **MongoDB** — with built-in trigger hooks, no models required.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from flash import FlashDB
|
|
39
|
+
|
|
40
|
+
flash = FlashDB("mysql", config)
|
|
41
|
+
flash.add("users", {"name": "John", "age": 25})
|
|
42
|
+
flash.where("users", {"age": {">": 18}})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 📦 Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install flashdb
|
|
51
|
+
|
|
52
|
+
# With specific driver:
|
|
53
|
+
pip install flashdb[mysql] # MySQL
|
|
54
|
+
pip install flashdb[postgres] # PostgreSQL
|
|
55
|
+
pip install flashdb[mongodb] # MongoDB
|
|
56
|
+
pip install flashdb[all] # All drivers
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🔌 Connection
|
|
62
|
+
|
|
63
|
+
### MySQL
|
|
64
|
+
```python
|
|
65
|
+
from flash import FlashDB
|
|
66
|
+
|
|
67
|
+
flash = FlashDB("mysql", {
|
|
68
|
+
"host": "localhost",
|
|
69
|
+
"port": 3306,
|
|
70
|
+
"user": "root",
|
|
71
|
+
"password": "1234",
|
|
72
|
+
"database": "mydb"
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### PostgreSQL
|
|
77
|
+
```python
|
|
78
|
+
flash = FlashDB("postgres", {
|
|
79
|
+
"host": "localhost",
|
|
80
|
+
"port": 5432,
|
|
81
|
+
"user": "postgres",
|
|
82
|
+
"password": "1234",
|
|
83
|
+
"database": "mydb"
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### MongoDB
|
|
88
|
+
```python
|
|
89
|
+
flash = FlashDB("mongodb", {
|
|
90
|
+
"host": "localhost",
|
|
91
|
+
"port": 27017,
|
|
92
|
+
"database": "mydb"
|
|
93
|
+
# Or use: "uri": "mongodb+srv://..."
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Context Manager
|
|
98
|
+
```python
|
|
99
|
+
with FlashDB("mysql", config) as flash:
|
|
100
|
+
flash.add("users", {"name": "John"})
|
|
101
|
+
# Connection auto-closed
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🧩 CRUD Operations
|
|
107
|
+
|
|
108
|
+
### ➕ Insert
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
# Single record
|
|
112
|
+
flash.add("users", {"name": "Alice", "age": 22})
|
|
113
|
+
|
|
114
|
+
# Bulk insert
|
|
115
|
+
flash.bulk_insert("users", [
|
|
116
|
+
{"name": "Alice", "age": 22},
|
|
117
|
+
{"name": "Bob", "age": 30},
|
|
118
|
+
])
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 📖 Read
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
# All records
|
|
125
|
+
flash.all("users")
|
|
126
|
+
|
|
127
|
+
# With filters
|
|
128
|
+
flash.where("users", {"name": "Alice"})
|
|
129
|
+
flash.where("users", {"age": {">": 18}})
|
|
130
|
+
|
|
131
|
+
# Specific fields
|
|
132
|
+
flash.select("users", fields=["name", "age"])
|
|
133
|
+
|
|
134
|
+
# Combined
|
|
135
|
+
flash.select("users",
|
|
136
|
+
fields=["name", "age"],
|
|
137
|
+
filters={"age": {">": 18}},
|
|
138
|
+
order_by="age",
|
|
139
|
+
limit=10
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Single record
|
|
143
|
+
flash.find_one("users", {"name": "Alice"})
|
|
144
|
+
|
|
145
|
+
# Count
|
|
146
|
+
flash.count("users", {"age": {">": 18}})
|
|
147
|
+
|
|
148
|
+
# Limit
|
|
149
|
+
flash.limit("users", 5)
|
|
150
|
+
|
|
151
|
+
# Paginate
|
|
152
|
+
flash.paginate("users", page=2, size=10)
|
|
153
|
+
# Returns: {"data": [...], "page": 2, "size": 10, "total": 42}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### ✏️ Update
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
flash.update("users", {"name": "Alice"}, {"age": 23})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 🗑️ Delete
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
flash.delete("users", {"name": "Alice"})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 🔍 Filter Operators
|
|
171
|
+
|
|
172
|
+
Flash uses a unified filter syntax that automatically translates to SQL or MongoDB:
|
|
173
|
+
|
|
174
|
+
| Flash Operator | SQL | MongoDB |
|
|
175
|
+
|---------------|-----------|----------|
|
|
176
|
+
| `>` | `>` | `$gt` |
|
|
177
|
+
| `<` | `<` | `$lt` |
|
|
178
|
+
| `>=` | `>=` | `$gte` |
|
|
179
|
+
| `<=` | `<=` | `$lte` |
|
|
180
|
+
| `!=` | `!=` | `$ne` |
|
|
181
|
+
| `in` | `IN` | `$in` |
|
|
182
|
+
| `not in` | `NOT IN` | `$nin` |
|
|
183
|
+
| `like` | `LIKE` | `$regex` |
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
flash.where("users", {"age": {">": 18}})
|
|
187
|
+
flash.where("users", {"role": {"in": ["admin", "mod"]}})
|
|
188
|
+
flash.where("users", {"name": {"like": "Jo%"}})
|
|
189
|
+
flash.where("users", {"score": {">=": 80, "<=": 100}})
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 🔔 Trigger Hooks
|
|
195
|
+
|
|
196
|
+
Flash supports before/after hooks for all operations — even on MongoDB where native triggers don't exist.
|
|
197
|
+
|
|
198
|
+
### Decorator Style
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
@flash.before_insert("users")
|
|
202
|
+
def validate(data):
|
|
203
|
+
if not data.get("name"):
|
|
204
|
+
raise ValueError("Name is required")
|
|
205
|
+
|
|
206
|
+
@flash.after_insert("users")
|
|
207
|
+
def on_created(data, result):
|
|
208
|
+
print(f"New user created with ID: {result}")
|
|
209
|
+
|
|
210
|
+
@flash.before_update("users")
|
|
211
|
+
def log_update(payload):
|
|
212
|
+
print("Updating:", payload["filters"], "->", payload["data"])
|
|
213
|
+
|
|
214
|
+
@flash.after_delete("users")
|
|
215
|
+
def on_deleted(filters, count):
|
|
216
|
+
print(f"Deleted {count} record(s)")
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Programmatic Style
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
def audit_log(data):
|
|
223
|
+
print("Insert:", data)
|
|
224
|
+
|
|
225
|
+
flash.add_hook("before", "insert", "users", audit_log)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Available Hooks
|
|
229
|
+
|
|
230
|
+
| Hook | When it fires |
|
|
231
|
+
|-----------------------------|--------------------------------|
|
|
232
|
+
| `before_insert(table)` | Before `add()` or `bulk_insert()` |
|
|
233
|
+
| `after_insert(table)` | After `add()` or `bulk_insert()` |
|
|
234
|
+
| `before_update(table)` | Before `update()` |
|
|
235
|
+
| `after_update(table)` | After `update()` |
|
|
236
|
+
| `before_delete(table)` | Before `delete()` |
|
|
237
|
+
| `after_delete(table)` | After `delete()` |
|
|
238
|
+
| `before_select(table)` | Before `all()`, `select()`, `where()` |
|
|
239
|
+
| `after_select(table)` | After any read operation |
|
|
240
|
+
|
|
241
|
+
### Manage Hooks
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
flash.list_hooks() # See all registered hooks
|
|
245
|
+
flash.clear_hooks() # Remove all hooks
|
|
246
|
+
flash.clear_hooks("users") # Remove hooks for one table
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 📄 Schema Operations
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
# Create table/collection
|
|
255
|
+
flash.create_table("users", {
|
|
256
|
+
"id": "int",
|
|
257
|
+
"name": "str",
|
|
258
|
+
"email": "str",
|
|
259
|
+
"age": "int",
|
|
260
|
+
"score": "float"
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
# Drop table
|
|
264
|
+
flash.drop_table("users")
|
|
265
|
+
|
|
266
|
+
# Truncate (keep structure, delete data)
|
|
267
|
+
flash.truncate("users")
|
|
268
|
+
|
|
269
|
+
# List tables
|
|
270
|
+
flash.show_tables()
|
|
271
|
+
|
|
272
|
+
# Describe structure
|
|
273
|
+
flash.describe("users")
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Supported Type Strings
|
|
277
|
+
|
|
278
|
+
| Flash Type | MySQL | PostgreSQL |
|
|
279
|
+
|-----------|----------------|----------------|
|
|
280
|
+
| `int` | INT | INTEGER |
|
|
281
|
+
| `str` | VARCHAR(255) | VARCHAR(255) |
|
|
282
|
+
| `text` | TEXT | TEXT |
|
|
283
|
+
| `float` | FLOAT | REAL |
|
|
284
|
+
| `bool` | TINYINT(1) | BOOLEAN |
|
|
285
|
+
| `date` | DATE | DATE |
|
|
286
|
+
| `datetime`| DATETIME | TIMESTAMP |
|
|
287
|
+
| `json` | JSON | JSONB |
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 🔐 Transactions (SQL)
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
flash.begin()
|
|
295
|
+
try:
|
|
296
|
+
flash.add("accounts", {"user": "Alice", "balance": 500})
|
|
297
|
+
flash.update("accounts", {"user": "Bob"}, {"balance": 100})
|
|
298
|
+
flash.commit()
|
|
299
|
+
except Exception:
|
|
300
|
+
flash.rollback()
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 🧰 Raw Queries
|
|
306
|
+
|
|
307
|
+
```python
|
|
308
|
+
# SQL
|
|
309
|
+
flash.raw("SELECT * FROM users WHERE age > %s", [18])
|
|
310
|
+
|
|
311
|
+
# MongoDB (pass raw filter dict)
|
|
312
|
+
flash.raw({"age": {"$gt": 18}}, table="users")
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## 🍃 MongoDB-Specific
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
# Aggregation pipeline
|
|
321
|
+
flash.aggregate("orders", [
|
|
322
|
+
{"$match": {"status": "paid"}},
|
|
323
|
+
{"$group": {"_id": "$user_id", "total": {"$sum": "$amount"}}},
|
|
324
|
+
{"$sort": {"total": -1}}
|
|
325
|
+
])
|
|
326
|
+
|
|
327
|
+
# Create index
|
|
328
|
+
flash.create_index("users", "email", unique=True)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## 🔧 Utilities
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
flash.ping() # True if connection is alive
|
|
337
|
+
flash.close() # Close connection
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## 📁 Project Structure
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
flash/
|
|
346
|
+
├── flash/
|
|
347
|
+
│ ├── __init__.py # Package entry point
|
|
348
|
+
│ ├── core.py # FlashDB main class
|
|
349
|
+
│ ├── filters.py # Filter/query translation
|
|
350
|
+
│ ├── triggers.py # Hook/trigger system
|
|
351
|
+
│ ├── exceptions.py # Custom exceptions
|
|
352
|
+
│ └── adapters/
|
|
353
|
+
│ ├── __init__.py
|
|
354
|
+
│ ├── mysql_adapter.py
|
|
355
|
+
│ ├── postgres_adapter.py
|
|
356
|
+
│ └── mongo_adapter.py
|
|
357
|
+
├── setup.py
|
|
358
|
+
└── README.md
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## 📜 License
|
|
364
|
+
|
|
365
|
+
MIT © Flash Team
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
from setuptools import setup, find_packages
|
|
2
2
|
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as f:
|
|
4
|
+
long_description = f.read()
|
|
5
|
+
|
|
3
6
|
setup(
|
|
4
7
|
name="pyflashdb",
|
|
5
|
-
version="1.0.
|
|
8
|
+
version="1.0.2",
|
|
6
9
|
author="Flash Team",
|
|
7
10
|
description="A unified, trigger-aware database interface for MySQL, PostgreSQL, and MongoDB.",
|
|
8
|
-
long_description=
|
|
11
|
+
long_description=long_description,
|
|
9
12
|
long_description_content_type="text/markdown",
|
|
10
13
|
packages=find_packages(),
|
|
11
14
|
python_requires=">=3.8",
|
pyflashdb-1.0.1/PKG-INFO
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pyflashdb
|
|
3
|
-
Version: 1.0.1
|
|
4
|
-
Summary: A unified, trigger-aware database interface for MySQL, PostgreSQL, and MongoDB.
|
|
5
|
-
Author: Flash Team
|
|
6
|
-
Keywords: database mysql postgresql mongodb orm crud flash unified
|
|
7
|
-
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
-
Classifier: Operating System :: OS Independent
|
|
10
|
-
Classifier: Topic :: Database
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Requires-Python: >=3.8
|
|
13
|
-
Description-Content-Type: text/markdown
|
|
14
|
-
Provides-Extra: mysql
|
|
15
|
-
Requires-Dist: mysql-connector-python>=8.0; extra == "mysql"
|
|
16
|
-
Provides-Extra: postgres
|
|
17
|
-
Requires-Dist: psycopg2-binary>=2.9; extra == "postgres"
|
|
18
|
-
Provides-Extra: mongodb
|
|
19
|
-
Requires-Dist: pymongo>=4.0; extra == "mongodb"
|
|
20
|
-
Provides-Extra: all
|
|
21
|
-
Requires-Dist: mysql-connector-python>=8.0; extra == "all"
|
|
22
|
-
Requires-Dist: psycopg2-binary>=2.9; extra == "all"
|
|
23
|
-
Requires-Dist: pymongo>=4.0; extra == "all"
|
|
24
|
-
Dynamic: author
|
|
25
|
-
Dynamic: classifier
|
|
26
|
-
Dynamic: description
|
|
27
|
-
Dynamic: description-content-type
|
|
28
|
-
Dynamic: keywords
|
|
29
|
-
Dynamic: provides-extra
|
|
30
|
-
Dynamic: requires-python
|
|
31
|
-
Dynamic: summary
|
|
32
|
-
|
|
33
|
-
# flash
|
|
34
|
-
A lightweight, multi-database Python library that provides simple CRUD operations, unified query syntax, and trigger hooks with minimal setup
|
pyflashdb-1.0.1/README.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pyflashdb
|
|
3
|
-
Version: 1.0.1
|
|
4
|
-
Summary: A unified, trigger-aware database interface for MySQL, PostgreSQL, and MongoDB.
|
|
5
|
-
Author: Flash Team
|
|
6
|
-
Keywords: database mysql postgresql mongodb orm crud flash unified
|
|
7
|
-
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
-
Classifier: Operating System :: OS Independent
|
|
10
|
-
Classifier: Topic :: Database
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Requires-Python: >=3.8
|
|
13
|
-
Description-Content-Type: text/markdown
|
|
14
|
-
Provides-Extra: mysql
|
|
15
|
-
Requires-Dist: mysql-connector-python>=8.0; extra == "mysql"
|
|
16
|
-
Provides-Extra: postgres
|
|
17
|
-
Requires-Dist: psycopg2-binary>=2.9; extra == "postgres"
|
|
18
|
-
Provides-Extra: mongodb
|
|
19
|
-
Requires-Dist: pymongo>=4.0; extra == "mongodb"
|
|
20
|
-
Provides-Extra: all
|
|
21
|
-
Requires-Dist: mysql-connector-python>=8.0; extra == "all"
|
|
22
|
-
Requires-Dist: psycopg2-binary>=2.9; extra == "all"
|
|
23
|
-
Requires-Dist: pymongo>=4.0; extra == "all"
|
|
24
|
-
Dynamic: author
|
|
25
|
-
Dynamic: classifier
|
|
26
|
-
Dynamic: description
|
|
27
|
-
Dynamic: description-content-type
|
|
28
|
-
Dynamic: keywords
|
|
29
|
-
Dynamic: provides-extra
|
|
30
|
-
Dynamic: requires-python
|
|
31
|
-
Dynamic: summary
|
|
32
|
-
|
|
33
|
-
# flash
|
|
34
|
-
A lightweight, multi-database Python library that provides simple CRUD operations, unified query syntax, and trigger hooks with minimal setup
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|