sql-athame 0.4.0a9__py3-none-any.whl → 0.4.0a10__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
1
  from .base import Fragment, sql
2
- from .dataclasses import ColumnInfo, ModelBase
2
+ from .dataclasses import ColumnInfo, ModelBase, ReplaceMultiplePlan
sql_athame/dataclasses.py CHANGED
@@ -8,6 +8,7 @@ from typing import (
8
8
  Annotated,
9
9
  Any,
10
10
  Callable,
11
+ Generic,
11
12
  Optional,
12
13
  TypeVar,
13
14
  Union,
@@ -251,7 +252,7 @@ class ModelBase:
251
252
  if ci.field.name not in exclude:
252
253
  if ci.serialize:
253
254
  env[f"_ser_{ci.field.name}"] = ci.serialize
254
- func.append(f"_ser_{ci.field.name}(self.{ci.field.name}), ")
255
+ func.append(f"_ser_{ci.field.name}(self.{ci.field.name}),")
255
256
  else:
256
257
  func.append(f"self.{ci.field.name},")
257
258
  func += ["]"]
@@ -588,7 +589,7 @@ class ModelBase:
588
589
  return env["equal_ignoring"]
589
590
 
590
591
  @classmethod
591
- async def replace_multiple(
592
+ async def plan_replace_multiple(
592
593
  cls: type[T],
593
594
  connection: Connection,
594
595
  rows: Union[Iterable[T], Iterable[Mapping[str, Any]]],
@@ -596,7 +597,7 @@ class ModelBase:
596
597
  where: Where,
597
598
  ignore: FieldNamesSet = (),
598
599
  insert_only: FieldNamesSet = (),
599
- ) -> tuple[list[T], list[T], list[T]]:
600
+ ) -> "ReplaceMultiplePlan[T]":
600
601
  ignore = sorted(set(ignore) | set(insert_only))
601
602
  equal_ignoring = cls._cached(
602
603
  ("equal_ignoring", tuple(ignore)),
@@ -620,14 +621,23 @@ class ModelBase:
620
621
 
621
622
  created = list(pending.values())
622
623
 
623
- if created or updated:
624
- await cls.upsert_multiple(
625
- connection, (*created, *updated), insert_only=insert_only
626
- )
627
- if deleted:
628
- await cls.delete_multiple(connection, deleted)
624
+ return ReplaceMultiplePlan(cls, insert_only, created, updated, deleted)
629
625
 
630
- return created, updated, deleted
626
+ @classmethod
627
+ async def replace_multiple(
628
+ cls: type[T],
629
+ connection: Connection,
630
+ rows: Union[Iterable[T], Iterable[Mapping[str, Any]]],
631
+ *,
632
+ where: Where,
633
+ ignore: FieldNamesSet = (),
634
+ insert_only: FieldNamesSet = (),
635
+ ) -> tuple[list[T], list[T], list[T]]:
636
+ plan = await cls.plan_replace_multiple(
637
+ connection, rows, where=where, ignore=ignore, insert_only=insert_only
638
+ )
639
+ await plan.execute(connection)
640
+ return plan.cud
631
641
 
632
642
  @classmethod
633
643
  def _get_differences_ignoring_fn(
@@ -694,6 +704,33 @@ class ModelBase:
694
704
  return created, updated_triples, deleted
695
705
 
696
706
 
707
+ @dataclass
708
+ class ReplaceMultiplePlan(Generic[T]):
709
+ model_class: type[T]
710
+ insert_only: FieldNamesSet
711
+ created: list[T]
712
+ updated: list[T]
713
+ deleted: list[T]
714
+
715
+ @property
716
+ def cud(self) -> tuple[list[T], list[T], list[T]]:
717
+ return (self.created, self.updated, self.deleted)
718
+
719
+ async def execute_upserts(self, connection: Connection) -> None:
720
+ if self.created or self.updated:
721
+ await self.model_class.upsert_multiple(
722
+ connection, (*self.created, *self.updated), insert_only=self.insert_only
723
+ )
724
+
725
+ async def execute_deletes(self, connection: Connection) -> None:
726
+ if self.deleted:
727
+ await self.model_class.delete_multiple(connection, self.deleted)
728
+
729
+ async def execute(self, connection: Connection) -> None:
730
+ await self.execute_upserts(connection)
731
+ await self.execute_deletes(connection)
732
+
733
+
697
734
  def chunked(lst, n):
698
735
  if type(lst) is not list:
699
736
  lst = list(lst)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql-athame
3
- Version: 0.4.0a9
3
+ Version: 0.4.0a10
4
4
  Summary: Python tool for slicing and dicing SQL
5
5
  Home-page: https://github.com/bdowning/sql-athame
6
6
  License: MIT
@@ -0,0 +1,11 @@
1
+ sql_athame/__init__.py,sha256=0GA9-xfnZ_gw7Vysx6t4iInQ2kGXos1EYwBI6Eb7auU,100
2
+ sql_athame/base.py,sha256=FR7EmC0VkX1VRgvAutSEfYSWhlEYpoqS1Kqxp1jHp6Y,10293
3
+ sql_athame/dataclasses.py,sha256=7qjAYP_dAD3hY_3txchBJfI5gURGmunOha6dDJdQjjw,25018
4
+ sql_athame/escape.py,sha256=kK101xXeFitlvuG-L_hvhdpgGJCtmRTprsn1yEfZKws,758
5
+ sql_athame/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ sql_athame/sqlalchemy.py,sha256=aWopfPh3j71XwKmcN_VcHRNlhscI0Sckd4AiyGf8Tpw,1293
7
+ sql_athame/types.py,sha256=FQ06l9Uc-vo57UrAarvnukILdV2gN1IaYUnHJ_bNYic,475
8
+ sql_athame-0.4.0a10.dist-info/LICENSE,sha256=xqV29vPFqITcKifYrGPgVIBjq4fdmLSwY3gRUtDKafg,1076
9
+ sql_athame-0.4.0a10.dist-info/METADATA,sha256=NU7Rhvp11MdZYD3YWtHJpauGOq8Nal8-cBa2EsMR0vE,12846
10
+ sql_athame-0.4.0a10.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
11
+ sql_athame-0.4.0a10.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- sql_athame/__init__.py,sha256=7OBIMZOcrD2pvfIL-rjD1IGZ3TNQbwyu76a9PWk-yYg,79
2
- sql_athame/base.py,sha256=FR7EmC0VkX1VRgvAutSEfYSWhlEYpoqS1Kqxp1jHp6Y,10293
3
- sql_athame/dataclasses.py,sha256=9Q-Z3itKyuqhR5u47bVBfA714uFbf-K4t1FPiFd8XAE,23792
4
- sql_athame/escape.py,sha256=kK101xXeFitlvuG-L_hvhdpgGJCtmRTprsn1yEfZKws,758
5
- sql_athame/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- sql_athame/sqlalchemy.py,sha256=aWopfPh3j71XwKmcN_VcHRNlhscI0Sckd4AiyGf8Tpw,1293
7
- sql_athame/types.py,sha256=FQ06l9Uc-vo57UrAarvnukILdV2gN1IaYUnHJ_bNYic,475
8
- sql_athame-0.4.0a9.dist-info/LICENSE,sha256=xqV29vPFqITcKifYrGPgVIBjq4fdmLSwY3gRUtDKafg,1076
9
- sql_athame-0.4.0a9.dist-info/METADATA,sha256=pf4xAdRJ7NuJaViLLWsQeq8LRIA78tY_YdOmPBjpFgg,12845
10
- sql_athame-0.4.0a9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
11
- sql_athame-0.4.0a9.dist-info/RECORD,,