tracktolib 0.63.0__tar.gz → 0.64.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.
- {tracktolib-0.63.0 → tracktolib-0.64.0}/PKG-INFO +1 -1
- {tracktolib-0.63.0 → tracktolib-0.64.0}/pyproject.toml +3 -3
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/pg/query.py +98 -14
- {tracktolib-0.63.0 → tracktolib-0.64.0}/README.md +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/__init__.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/api.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/http_utils.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/logs.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/notion/__init__.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/notion/fetch.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/notion/models.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/pg/__init__.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/pg/utils.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/pg_sync.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/pg_utils.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/s3/__init__.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/s3/minio.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/s3/s3.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/tests.py +0 -0
- {tracktolib-0.63.0 → tracktolib-0.64.0}/tracktolib/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tracktolib"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.64.0"
|
|
4
4
|
authors = [
|
|
5
5
|
{ email = "julien.brayere@tracktor.fr" }
|
|
6
6
|
]
|
|
@@ -38,7 +38,7 @@ pg = [
|
|
|
38
38
|
"rich>=13.6.0",
|
|
39
39
|
]
|
|
40
40
|
notion = [
|
|
41
|
-
"niquests>=3.15.2"
|
|
41
|
+
"niquests>=3.15.2"
|
|
42
42
|
]
|
|
43
43
|
|
|
44
44
|
[dependency-groups]
|
|
@@ -92,7 +92,7 @@ pythonPlatform = "Linux"
|
|
|
92
92
|
|
|
93
93
|
[tool.commitizen]
|
|
94
94
|
name = "cz_conventional_commits"
|
|
95
|
-
version = "0.
|
|
95
|
+
version = "0.64.0"
|
|
96
96
|
tag_format = "$version"
|
|
97
97
|
version_files = [
|
|
98
98
|
"pyproject.toml:version"
|
|
@@ -160,12 +160,34 @@ class PGInsertQuery(PGQuery):
|
|
|
160
160
|
def is_returning(self):
|
|
161
161
|
return self.returning is not None
|
|
162
162
|
|
|
163
|
+
def _get_values_query(self) -> str:
|
|
164
|
+
"""Generate the VALUES clause for the query."""
|
|
165
|
+
_columns = self.columns
|
|
166
|
+
num_cols = len(_columns)
|
|
167
|
+
|
|
168
|
+
if len(self.items) == 1 or not self.is_returning:
|
|
169
|
+
# Single row or no returning: simple placeholders
|
|
170
|
+
return ", ".join(f"${i + 1}" for i in range(num_cols))
|
|
171
|
+
else:
|
|
172
|
+
# Multiple rows with returning: generate all value groups
|
|
173
|
+
value_groups = []
|
|
174
|
+
for row_idx in range(len(self.items)):
|
|
175
|
+
offset = row_idx * num_cols
|
|
176
|
+
group = ", ".join(f"${offset + i + 1}" for i in range(num_cols))
|
|
177
|
+
value_groups.append(f"({group})")
|
|
178
|
+
return ", ".join(value_groups)
|
|
179
|
+
|
|
163
180
|
@property
|
|
164
181
|
def query(self) -> str:
|
|
165
182
|
_columns = self.columns
|
|
166
|
-
_values =
|
|
183
|
+
_values = self._get_values_query()
|
|
167
184
|
|
|
168
|
-
|
|
185
|
+
if len(self.items) > 1 and self.is_returning:
|
|
186
|
+
# For multi-row insert with returning, build full VALUES clause
|
|
187
|
+
_columns_str = ", ".join(_columns)
|
|
188
|
+
query = f"INSERT INTO {self.table} AS t ({_columns_str}) VALUES {_values}"
|
|
189
|
+
else:
|
|
190
|
+
query = _get_insert_query(self.table, _columns, _values)
|
|
169
191
|
|
|
170
192
|
# Conflict
|
|
171
193
|
if self.on_conflict:
|
|
@@ -184,13 +206,14 @@ class PGInsertQuery(PGQuery):
|
|
|
184
206
|
if self.returning is not None:
|
|
185
207
|
if self.returning.returning_ids is None:
|
|
186
208
|
raise ValueError("No returning ids found")
|
|
187
|
-
|
|
188
|
-
query = _get_returning_query(query, self.returning.returning_ids)
|
|
189
|
-
else:
|
|
190
|
-
raise NotImplementedError("Cannot return value when inserting many.")
|
|
209
|
+
query = _get_returning_query(query, self.returning.returning_ids)
|
|
191
210
|
|
|
192
211
|
return query
|
|
193
212
|
|
|
213
|
+
def _get_flat_values(self) -> list:
|
|
214
|
+
"""Get all values as a flat list for multi-row insert with returning."""
|
|
215
|
+
return [val for item_values in self.iter_values() for val in item_values]
|
|
216
|
+
|
|
194
217
|
|
|
195
218
|
def get_update_fields(
|
|
196
219
|
item: dict,
|
|
@@ -341,6 +364,7 @@ async def insert_one(
|
|
|
341
364
|
await query.run(conn)
|
|
342
365
|
|
|
343
366
|
|
|
367
|
+
@overload
|
|
344
368
|
async def insert_many(
|
|
345
369
|
conn: _Connection,
|
|
346
370
|
table: str,
|
|
@@ -349,12 +373,53 @@ async def insert_many(
|
|
|
349
373
|
on_conflict: OnConflict | None = None,
|
|
350
374
|
fill: bool = False,
|
|
351
375
|
quote_columns: bool = False,
|
|
376
|
+
returning: None = None,
|
|
352
377
|
query_callback: QueryCallback[PGInsertQuery] | None = None,
|
|
353
|
-
):
|
|
354
|
-
|
|
378
|
+
) -> None: ...
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
@overload
|
|
382
|
+
async def insert_many(
|
|
383
|
+
conn: _Connection,
|
|
384
|
+
table: str,
|
|
385
|
+
items: list[dict],
|
|
386
|
+
*,
|
|
387
|
+
on_conflict: OnConflict | None = None,
|
|
388
|
+
fill: bool = False,
|
|
389
|
+
quote_columns: bool = False,
|
|
390
|
+
returning: str | list[str],
|
|
391
|
+
query_callback: QueryCallback[PGInsertQuery] | None = None,
|
|
392
|
+
) -> list[asyncpg.Record]: ...
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
async def insert_many(
|
|
396
|
+
conn: _Connection,
|
|
397
|
+
table: str,
|
|
398
|
+
items: list[dict],
|
|
399
|
+
*,
|
|
400
|
+
on_conflict: OnConflict | None = None,
|
|
401
|
+
fill: bool = False,
|
|
402
|
+
quote_columns: bool = False,
|
|
403
|
+
returning: str | list[str] | None = None,
|
|
404
|
+
query_callback: QueryCallback[PGInsertQuery] | None = None,
|
|
405
|
+
) -> list[asyncpg.Record] | None:
|
|
406
|
+
returning_values = [returning] if isinstance(returning, str) else returning
|
|
407
|
+
query = insert_pg(
|
|
408
|
+
table=table,
|
|
409
|
+
items=items,
|
|
410
|
+
on_conflict=on_conflict,
|
|
411
|
+
fill=fill,
|
|
412
|
+
quote_columns=quote_columns,
|
|
413
|
+
returning=returning_values,
|
|
414
|
+
)
|
|
355
415
|
if query_callback is not None:
|
|
356
416
|
query_callback(query)
|
|
357
|
-
|
|
417
|
+
|
|
418
|
+
if returning is not None:
|
|
419
|
+
return await conn.fetch(query.query, *query._get_flat_values())
|
|
420
|
+
else:
|
|
421
|
+
await query.run(conn)
|
|
422
|
+
return None
|
|
358
423
|
|
|
359
424
|
|
|
360
425
|
@overload
|
|
@@ -381,22 +446,41 @@ async def insert_returning(
|
|
|
381
446
|
) -> asyncpg.Record | None: ...
|
|
382
447
|
|
|
383
448
|
|
|
449
|
+
@overload
|
|
384
450
|
async def insert_returning(
|
|
385
451
|
conn: _Connection,
|
|
386
452
|
table: str,
|
|
387
|
-
item: dict,
|
|
453
|
+
item: list[dict],
|
|
454
|
+
returning: str | list[str],
|
|
455
|
+
on_conflict: OnConflict | None = None,
|
|
456
|
+
fill: bool = False,
|
|
457
|
+
query_callback: QueryCallback[PGInsertQuery] | None = None,
|
|
458
|
+
) -> list[asyncpg.Record]: ...
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
async def insert_returning(
|
|
462
|
+
conn: _Connection,
|
|
463
|
+
table: str,
|
|
464
|
+
item: dict | list[dict],
|
|
388
465
|
returning: list[str] | str,
|
|
389
466
|
on_conflict: OnConflict | None = None,
|
|
390
467
|
fill: bool = False,
|
|
391
468
|
query_callback: QueryCallback[PGInsertQuery] | None = None,
|
|
392
|
-
) -> asyncpg.Record | Any | None:
|
|
469
|
+
) -> asyncpg.Record | Any | list[asyncpg.Record] | None:
|
|
393
470
|
returning_values = [returning] if isinstance(returning, str) else returning
|
|
394
|
-
|
|
471
|
+
items = item if isinstance(item, list) else [item]
|
|
472
|
+
|
|
473
|
+
query = insert_pg(table=table, items=items, on_conflict=on_conflict, fill=fill, returning=returning_values)
|
|
395
474
|
if query_callback is not None:
|
|
396
475
|
query_callback(query)
|
|
397
|
-
fn = conn.fetchval if len(returning_values) == 1 and returning != "*" else conn.fetchrow
|
|
398
476
|
|
|
399
|
-
|
|
477
|
+
if len(items) > 1:
|
|
478
|
+
# Multi-row insert: use fetch() with flat values
|
|
479
|
+
return await conn.fetch(query.query, *query._get_flat_values())
|
|
480
|
+
else:
|
|
481
|
+
# Single row insert: use fetchval or fetchrow
|
|
482
|
+
fn = conn.fetchval if len(returning_values) == 1 and returning != "*" else conn.fetchrow
|
|
483
|
+
return await fn(query.query, *query.values)
|
|
400
484
|
|
|
401
485
|
|
|
402
486
|
async def fetch_count(conn: _Connection, query: str, *args) -> int:
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|