sql-athame 0.4.0a1__tar.gz → 0.4.0a2__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.
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/PKG-INFO +1 -1
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/pyproject.toml +1 -1
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/sql_athame/dataclasses.py +70 -3
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/LICENSE +0 -0
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/README.md +0 -0
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/sql_athame/__init__.py +0 -0
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/sql_athame/base.py +0 -0
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/sql_athame/escape.py +0 -0
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/sql_athame/py.typed +0 -0
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/sql_athame/sqlalchemy.py +0 -0
- {sql_athame-0.4.0a1 → sql_athame-0.4.0a2}/sql_athame/types.py +0 -0
@@ -100,12 +100,24 @@ class ModelBase(Mapping[str, Any]):
|
|
100
100
|
_cache: Dict[tuple, Any]
|
101
101
|
table_name: str
|
102
102
|
primary_key_names: Tuple[str, ...]
|
103
|
+
array_safe_insert: bool
|
103
104
|
|
104
105
|
def __init_subclass__(
|
105
|
-
cls,
|
106
|
+
cls,
|
107
|
+
*,
|
108
|
+
table_name: str,
|
109
|
+
primary_key: Union[FieldNames, str] = (),
|
110
|
+
insert_multiple_mode: str = "unnest",
|
111
|
+
**kwargs: Any,
|
106
112
|
):
|
107
113
|
cls._cache = {}
|
108
114
|
cls.table_name = table_name
|
115
|
+
if insert_multiple_mode == "array_safe":
|
116
|
+
cls.array_safe_insert = True
|
117
|
+
elif insert_multiple_mode == "unnest":
|
118
|
+
cls.array_safe_insert = False
|
119
|
+
else:
|
120
|
+
raise ValueError("Unknown `insert_multiple_mode`")
|
109
121
|
if isinstance(primary_key, str):
|
110
122
|
cls.primary_key_names = (primary_key,)
|
111
123
|
else:
|
@@ -407,19 +419,69 @@ class ModelBase(Mapping[str, Any]):
|
|
407
419
|
)
|
408
420
|
|
409
421
|
@classmethod
|
410
|
-
|
422
|
+
def insert_multiple_array_safe_sql(cls: Type[T], rows: Iterable[T]) -> Fragment:
|
423
|
+
return sql(
|
424
|
+
"INSERT INTO {table} ({fields}) VALUES {values}",
|
425
|
+
table=cls.table_name_sql(),
|
426
|
+
fields=sql.list(cls.field_names_sql()),
|
427
|
+
values=sql.list(
|
428
|
+
sql("({})", sql.list(row.field_values_sql(default_none=True)))
|
429
|
+
for row in rows
|
430
|
+
),
|
431
|
+
)
|
432
|
+
|
433
|
+
@classmethod
|
434
|
+
async def insert_multiple_unnest(
|
411
435
|
cls: Type[T], connection_or_pool: Union[Connection, Pool], rows: Iterable[T]
|
412
436
|
) -> str:
|
413
437
|
return await connection_or_pool.execute(*cls.insert_multiple_sql(rows))
|
414
438
|
|
415
439
|
@classmethod
|
416
|
-
async def
|
440
|
+
async def insert_multiple_array_safe(
|
441
|
+
cls: Type[T], connection_or_pool: Union[Connection, Pool], rows: Iterable[T]
|
442
|
+
) -> str:
|
443
|
+
for chunk in chunked(rows, 100):
|
444
|
+
last = await connection_or_pool.execute(
|
445
|
+
*cls.insert_multiple_array_safe_sql(chunk)
|
446
|
+
)
|
447
|
+
return last
|
448
|
+
|
449
|
+
@classmethod
|
450
|
+
async def insert_multiple(
|
451
|
+
cls: Type[T], connection_or_pool: Union[Connection, Pool], rows: Iterable[T]
|
452
|
+
) -> str:
|
453
|
+
if cls.array_safe_insert:
|
454
|
+
return await cls.insert_multiple_array_safe(connection_or_pool, rows)
|
455
|
+
else:
|
456
|
+
return await cls.insert_multiple_unnest(connection_or_pool, rows)
|
457
|
+
|
458
|
+
@classmethod
|
459
|
+
async def upsert_multiple_unnest(
|
417
460
|
cls: Type[T], connection_or_pool: Union[Connection, Pool], rows: Iterable[T]
|
418
461
|
) -> str:
|
419
462
|
return await connection_or_pool.execute(
|
420
463
|
*cls.upsert_sql(cls.insert_multiple_sql(rows))
|
421
464
|
)
|
422
465
|
|
466
|
+
@classmethod
|
467
|
+
async def upsert_multiple_array_safe(
|
468
|
+
cls: Type[T], connection_or_pool: Union[Connection, Pool], rows: Iterable[T]
|
469
|
+
) -> str:
|
470
|
+
for chunk in chunked(rows, 100):
|
471
|
+
last = await connection_or_pool.execute(
|
472
|
+
*cls.upsert_sql(cls.insert_multiple_array_safe_sql(chunk))
|
473
|
+
)
|
474
|
+
return last
|
475
|
+
|
476
|
+
@classmethod
|
477
|
+
async def upsert_multiple(
|
478
|
+
cls: Type[T], connection_or_pool: Union[Connection, Pool], rows: Iterable[T]
|
479
|
+
) -> str:
|
480
|
+
if cls.array_safe_insert:
|
481
|
+
return await cls.upsert_multiple_array_safe(connection_or_pool, rows)
|
482
|
+
else:
|
483
|
+
return await cls.upsert_multiple_unnest(connection_or_pool, rows)
|
484
|
+
|
423
485
|
@classmethod
|
424
486
|
def _get_equal_ignoring_fn(
|
425
487
|
cls: Type[T], ignore: FieldNamesSet = ()
|
@@ -530,3 +592,8 @@ class ModelBase(Mapping[str, Any]):
|
|
530
592
|
await cls.delete_multiple(connection, deleted)
|
531
593
|
|
532
594
|
return created, updated_triples, deleted
|
595
|
+
|
596
|
+
|
597
|
+
def chunked(lst, n):
|
598
|
+
for i in range(0, len(lst), n):
|
599
|
+
yield lst[i : i + n]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|