pydoptic-sql 0.0.2.post1.dev1__tar.gz → 0.0.2.post1.dev2__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.
Files changed (28) hide show
  1. {pydoptic_sql-0.0.2.post1.dev1/src/pydoptic_sql.egg-info → pydoptic_sql-0.0.2.post1.dev2}/PKG-INFO +1 -1
  2. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/sql_computed.py +1 -1
  3. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/sql_query.py +11 -11
  4. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/sql_service.py +42 -42
  5. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2/src/pydoptic_sql.egg-info}/PKG-INFO +1 -1
  6. pydoptic_sql-0.0.2.post1.dev2/src/pydoptic_sql.egg-info/scm_version.json +8 -0
  7. pydoptic_sql-0.0.2.post1.dev1/src/pydoptic_sql.egg-info/scm_version.json +0 -8
  8. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/LICENSE +0 -0
  9. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/README.md +0 -0
  10. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/pyproject.toml +0 -0
  11. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/setup.cfg +0 -0
  12. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/__init__.py +0 -0
  13. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/py.typed +0 -0
  14. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/sql_constraint.py +0 -0
  15. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/sql_having.py +0 -0
  16. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/sql_order.py +0 -0
  17. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql/sql_table.py +0 -0
  18. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql.egg-info/SOURCES.txt +0 -0
  19. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql.egg-info/dependency_links.txt +0 -0
  20. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql.egg-info/requires.txt +0 -0
  21. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql.egg-info/scm_file_list.json +0 -0
  22. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/src/pydoptic_sql.egg-info/top_level.txt +0 -0
  23. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/test/test_sql_computed.py +0 -0
  24. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/test/test_sql_constraint.py +0 -0
  25. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/test/test_sql_having.py +0 -0
  26. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/test/test_sql_params.py +0 -0
  27. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/test/test_sql_query.py +0 -0
  28. {pydoptic_sql-0.0.2.post1.dev1 → pydoptic_sql-0.0.2.post1.dev2}/test/test_sql_service.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydoptic-sql
3
- Version: 0.0.2.post1.dev1
3
+ Version: 0.0.2.post1.dev2
4
4
  Summary: A type-safe SQL query builder built on pydoptic
5
5
  Author: John Hungerford
6
6
  License-Expression: MIT
@@ -19,7 +19,7 @@ class AggregateFunction(Enum):
19
19
  class ComputedResult(Selectable['ComputedResult']):
20
20
  """
21
21
  Dict-backed holder for the computed (aggregate) columns of a query result row, keyed by each
22
- `Computed`'s alias. Mirrors `PartialModel`'s shape but isn't backed by a model class -- there's
22
+ `Computed`'s alias. Mirrors `Partial`'s shape but isn't backed by a model class -- there's
23
23
  no schema behind an aggregate expression, just whatever aliases the query selected.
24
24
  """
25
25
  __slots__ = ['_dict']
@@ -2,7 +2,7 @@
2
2
  from dataclasses import dataclass
3
3
  from enum import Enum
4
4
  from typing import Any, Generic, List, Sequence, Tuple, Type, TypeVar, cast
5
- from pydoptic import PartialModel
5
+ from pydoptic import Partial
6
6
  from pydoptic.selector import PropSelect, Prop, PropOpt, Param
7
7
  from pydoptic_sql import SqlTable
8
8
  from pydoptic_sql.sql_constraint import A, TC, TC1, TC2, TC3, Constraint, Constraint2, Constraint3, Constraint4, _qualified_label
@@ -25,7 +25,7 @@ from pydoptic_sql.sql_table import (
25
25
  R = TypeVar('R')
26
26
 
27
27
  class SqlQuery(Generic[R]):
28
- # R is the result type of executing the query (e.g. PartialModel[TC], or None); table type(s) are tracked separately per subclass.
28
+ # R is the result type of executing the query (e.g. Partial[TC], or None); table type(s) are tracked separately per subclass.
29
29
  def to_sql(self) -> str:
30
30
  """Render this query as a single SQL string with values interpolated -- for display/debugging only."""
31
31
  raise NotImplementedError()
@@ -146,7 +146,7 @@ class JoinType(Enum):
146
146
  # calling incr_arity() on them when set, and QueryN/ComputedQueryN are directly executable
147
147
  # (to_sql()/to_sql_params()) at every stage, builder and "terminal" alike -- hence one class per arity
148
148
  # instead of two. select_computed(_more) still splits off into a separate ComputedQueryN from QueryN,
149
- # since the result type R differs (PartialModel[...] vs Tuple[..., ComputedResult]) and R can't vary
149
+ # since the result type R differs (Partial[...] vs Tuple[..., ComputedResult]) and R can't vary
150
150
  # at runtime for a single dataclass.
151
151
  #
152
152
  # _order_by/_group_by/_computed still widen by one union member per table added (rather than gaining
@@ -155,7 +155,7 @@ class JoinType(Enum):
155
155
  # exactly as valid after it, with no re-wrapping needed.
156
156
 
157
157
  @dataclass(frozen=True)
158
- class Query1(Generic[TC], SqlQuery[PartialModel[TC]]):
158
+ class Query1(Generic[TC], SqlQuery[Partial[TC]]):
159
159
  table1: Type[TC]
160
160
  _selection: Sequence[PropSelect[TC, Any]] | None = None
161
161
  _where: Constraint[TC] | None = None
@@ -225,7 +225,7 @@ class Query1(Generic[TC], SqlQuery[PartialModel[TC]]):
225
225
  return f'SELECT {selections} FROM {self.table1.__name__.lower()} WHERE {where_clause}{group_by_clause}{order_by_clause};', params
226
226
 
227
227
  @dataclass(frozen=True)
228
- class ComputedQuery1(Generic[TC], SqlQuery[Tuple[PartialModel[TC], ComputedResult]]):
228
+ class ComputedQuery1(Generic[TC], SqlQuery[Tuple[Partial[TC], ComputedResult]]):
229
229
  table1: Type[TC]
230
230
  _selection: Sequence[PropSelect[TC, Any]] | None = None
231
231
  _where: Constraint[TC] | None = None
@@ -460,7 +460,7 @@ class DeleteQuery(Generic[TC], SqlQuery[None]):
460
460
  # --- 2 tables ---
461
461
 
462
462
  @dataclass(frozen=True)
463
- class Query2(Generic[TC, TC1], SqlQuery[Tuple[PartialModel[TC], PartialModel[TC1]]]):
463
+ class Query2(Generic[TC, TC1], SqlQuery[Tuple[Partial[TC], Partial[TC1]]]):
464
464
  table1: Type[TC]
465
465
  table2: Type[TC1]
466
466
  join_type_2: JoinType
@@ -558,7 +558,7 @@ class Query2(Generic[TC, TC1], SqlQuery[Tuple[PartialModel[TC], PartialModel[TC1
558
558
  return f'SELECT {selections} FROM {from_clause} WHERE {where_clause}{group_by_clause}{order_by_clause};', params
559
559
 
560
560
  @dataclass(frozen=True)
561
- class ComputedQuery2(Generic[TC, TC1], SqlQuery[Tuple[PartialModel[TC], PartialModel[TC1], ComputedResult]]):
561
+ class ComputedQuery2(Generic[TC, TC1], SqlQuery[Tuple[Partial[TC], Partial[TC1], ComputedResult]]):
562
562
  table1: Type[TC]
563
563
  table2: Type[TC1]
564
564
  join_type_2: JoinType
@@ -679,7 +679,7 @@ class ComputedQuery2(Generic[TC, TC1], SqlQuery[Tuple[PartialModel[TC], PartialM
679
679
  # --- 3 tables ---
680
680
 
681
681
  @dataclass(frozen=True)
682
- class Query3(Generic[TC, TC1, TC2], SqlQuery[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2]]]):
682
+ class Query3(Generic[TC, TC1, TC2], SqlQuery[Tuple[Partial[TC], Partial[TC1], Partial[TC2]]]):
683
683
  table1: Type[TC]
684
684
  table2: Type[TC1]
685
685
  table3: Type[TC2]
@@ -787,7 +787,7 @@ class Query3(Generic[TC, TC1, TC2], SqlQuery[Tuple[PartialModel[TC], PartialMode
787
787
  return f'SELECT {selections} FROM {from_clause} WHERE {where_clause}{group_by_clause}{order_by_clause};', params
788
788
 
789
789
  @dataclass(frozen=True)
790
- class ComputedQuery3(Generic[TC, TC1, TC2], SqlQuery[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], ComputedResult]]):
790
+ class ComputedQuery3(Generic[TC, TC1, TC2], SqlQuery[Tuple[Partial[TC], Partial[TC1], Partial[TC2], ComputedResult]]):
791
791
  table1: Type[TC]
792
792
  table2: Type[TC1]
793
793
  table3: Type[TC2]
@@ -918,7 +918,7 @@ class ComputedQuery3(Generic[TC, TC1, TC2], SqlQuery[Tuple[PartialModel[TC], Par
918
918
  # --- 4 tables ---
919
919
 
920
920
  @dataclass(frozen=True)
921
- class Query4(Generic[TC, TC1, TC2, TC3], SqlQuery[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3]]]):
921
+ class Query4(Generic[TC, TC1, TC2, TC3], SqlQuery[Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3]]]):
922
922
  table1: Type[TC]
923
923
  table2: Type[TC1]
924
924
  table3: Type[TC2]
@@ -1022,7 +1022,7 @@ class Query4(Generic[TC, TC1, TC2, TC3], SqlQuery[Tuple[PartialModel[TC], Partia
1022
1022
  return f'SELECT {selections} FROM {from_clause} WHERE {where_clause}{group_by_clause}{order_by_clause};', params
1023
1023
 
1024
1024
  @dataclass(frozen=True)
1025
- class ComputedQuery4(Generic[TC, TC1, TC2, TC3], SqlQuery[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3], ComputedResult]]):
1025
+ class ComputedQuery4(Generic[TC, TC1, TC2, TC3], SqlQuery[Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3], ComputedResult]]):
1026
1026
  table1: Type[TC]
1027
1027
  table2: Type[TC1]
1028
1028
  table3: Type[TC2]
@@ -4,7 +4,7 @@ from contextlib import contextmanager
4
4
  from dataclasses import dataclass
5
5
  from typing import Any, Dict, Generic, Iterator, List, Sequence, Tuple, Type, cast
6
6
 
7
- from pydoptic.base_model import PartialModel
7
+ from pydoptic.base_model import Partial
8
8
  from pydoptic.selector import PropSelect
9
9
  from pydoptic_sql import SqlQuery
10
10
  from pydoptic_sql.sql_computed import Computed, ComputedResult
@@ -53,58 +53,58 @@ def _computed_record(computed: Sequence[Computed[Any, Any]], sql_record: Tuple[A
53
53
  return ComputedResult(**{c.label: sql_record[offset + i] for i, c in enumerate(computed)})
54
54
 
55
55
  @dataclass
56
- class PsycoPgSqlResponse(Generic[TC], SqlResponse[PartialModel[TC]]):
56
+ class PsycoPgSqlResponse(Generic[TC], SqlResponse[Partial[TC]]):
57
57
  model: Type[TC]
58
58
  cursor: Cursor
59
59
  selection: Sequence[PropSelect[TC, Any]]
60
60
 
61
- def __make_record(self, sql_record: Tuple[Any,...]) -> PartialModel[TC]:
61
+ def __make_record(self, sql_record: Tuple[Any,...]) -> Partial[TC]:
62
62
  data: Dict[str, Any] = {}
63
63
  for i, prop in enumerate(self.selection):
64
64
  data[prop.label] = sql_record[i]
65
- return PartialModel(self.model, **data)
65
+ return Partial(self.model, **data)
66
66
 
67
- def fetchone(self) -> PartialModel[TC] | None:
67
+ def fetchone(self) -> Partial[TC] | None:
68
68
  result = self.cursor.fetchone()
69
69
  if result is not None:
70
70
  return self.__make_record(result)
71
71
  return None
72
72
 
73
- def stream(self) -> Iterator[PartialModel[TC]]:
73
+ def stream(self) -> Iterator[Partial[TC]]:
74
74
  for row in self.cursor:
75
75
  yield self.__make_record(row)
76
76
 
77
77
  @dataclass
78
- class PsycoPgComputedResponse1(Generic[TC], SqlResponse[Tuple[PartialModel[TC], ComputedResult]]):
78
+ class PsycoPgComputedResponse1(Generic[TC], SqlResponse[Tuple[Partial[TC], ComputedResult]]):
79
79
  model: Type[TC]
80
80
  cursor: Cursor
81
81
  selection: Sequence[PropSelect[TC, Any]]
82
82
  computed: Sequence[Computed[TC, Any]]
83
83
 
84
- def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[PartialModel[TC], ComputedResult]:
84
+ def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[Partial[TC], ComputedResult]:
85
85
  data: Dict[str, Any] = {}
86
86
  for i, prop in enumerate(self.selection):
87
87
  data[prop.label] = sql_record[i]
88
- return PartialModel(self.model, **data), _computed_record(self.computed, sql_record, len(self.selection))
88
+ return Partial(self.model, **data), _computed_record(self.computed, sql_record, len(self.selection))
89
89
 
90
- def fetchone(self) -> Tuple[PartialModel[TC], ComputedResult] | None:
90
+ def fetchone(self) -> Tuple[Partial[TC], ComputedResult] | None:
91
91
  result = self.cursor.fetchone()
92
92
  if result is not None:
93
93
  return self.__make_record(result)
94
94
  return None
95
95
 
96
- def stream(self) -> Iterator[Tuple[PartialModel[TC], ComputedResult]]:
96
+ def stream(self) -> Iterator[Tuple[Partial[TC], ComputedResult]]:
97
97
  for row in self.cursor:
98
98
  yield self.__make_record(row)
99
99
 
100
100
  @dataclass
101
- class PsycoPgJoinResponse2(Generic[TC, TC1], SqlResponse[Tuple[PartialModel[TC], PartialModel[TC1]]]):
101
+ class PsycoPgJoinResponse2(Generic[TC, TC1], SqlResponse[Tuple[Partial[TC], Partial[TC1]]]):
102
102
  table1: Type[TC]
103
103
  table2: Type[TC1]
104
104
  cursor: Cursor
105
105
  selection: Sequence[PropSelect[TC, Any] | PropSelect[TC1, Any]]
106
106
 
107
- def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[PartialModel[TC], PartialModel[TC1]]:
107
+ def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[Partial[TC], Partial[TC1]]:
108
108
  data1: Dict[str, Any] = {}
109
109
  data2: Dict[str, Any] = {}
110
110
  for i, prop in enumerate(self.selection):
@@ -112,27 +112,27 @@ class PsycoPgJoinResponse2(Generic[TC, TC1], SqlResponse[Tuple[PartialModel[TC],
112
112
  data1[prop.label] = sql_record[i]
113
113
  else:
114
114
  data2[prop.label] = sql_record[i]
115
- return PartialModel(self.table1, **data1), PartialModel(self.table2, **data2)
115
+ return Partial(self.table1, **data1), Partial(self.table2, **data2)
116
116
 
117
- def fetchone(self) -> Tuple[PartialModel[TC], PartialModel[TC1]] | None:
117
+ def fetchone(self) -> Tuple[Partial[TC], Partial[TC1]] | None:
118
118
  result = self.cursor.fetchone()
119
119
  if result is not None:
120
120
  return self.__make_record(result)
121
121
  return None
122
122
 
123
- def stream(self) -> Iterator[Tuple[PartialModel[TC], PartialModel[TC1]]]:
123
+ def stream(self) -> Iterator[Tuple[Partial[TC], Partial[TC1]]]:
124
124
  for row in self.cursor:
125
125
  yield self.__make_record(row)
126
126
 
127
127
  @dataclass
128
- class PsycoPgComputedResponse2(Generic[TC, TC1], SqlResponse[Tuple[PartialModel[TC], PartialModel[TC1], ComputedResult]]):
128
+ class PsycoPgComputedResponse2(Generic[TC, TC1], SqlResponse[Tuple[Partial[TC], Partial[TC1], ComputedResult]]):
129
129
  table1: Type[TC]
130
130
  table2: Type[TC1]
131
131
  cursor: Cursor
132
132
  selection: Sequence[PropSelect[TC, Any] | PropSelect[TC1, Any]]
133
133
  computed: Sequence[Computed[TC, Any] | Computed[TC1, Any]]
134
134
 
135
- def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[PartialModel[TC], PartialModel[TC1], ComputedResult]:
135
+ def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[Partial[TC], Partial[TC1], ComputedResult]:
136
136
  data1: Dict[str, Any] = {}
137
137
  data2: Dict[str, Any] = {}
138
138
  for i, prop in enumerate(self.selection):
@@ -140,27 +140,27 @@ class PsycoPgComputedResponse2(Generic[TC, TC1], SqlResponse[Tuple[PartialModel[
140
140
  data1[prop.label] = sql_record[i]
141
141
  else:
142
142
  data2[prop.label] = sql_record[i]
143
- return PartialModel(self.table1, **data1), PartialModel(self.table2, **data2), _computed_record(self.computed, sql_record, len(self.selection))
143
+ return Partial(self.table1, **data1), Partial(self.table2, **data2), _computed_record(self.computed, sql_record, len(self.selection))
144
144
 
145
- def fetchone(self) -> Tuple[PartialModel[TC], PartialModel[TC1], ComputedResult] | None:
145
+ def fetchone(self) -> Tuple[Partial[TC], Partial[TC1], ComputedResult] | None:
146
146
  result = self.cursor.fetchone()
147
147
  if result is not None:
148
148
  return self.__make_record(result)
149
149
  return None
150
150
 
151
- def stream(self) -> Iterator[Tuple[PartialModel[TC], PartialModel[TC1], ComputedResult]]:
151
+ def stream(self) -> Iterator[Tuple[Partial[TC], Partial[TC1], ComputedResult]]:
152
152
  for row in self.cursor:
153
153
  yield self.__make_record(row)
154
154
 
155
155
  @dataclass
156
- class PsycoPgJoinResponse3(Generic[TC, TC1, TC2], SqlResponse[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2]]]):
156
+ class PsycoPgJoinResponse3(Generic[TC, TC1, TC2], SqlResponse[Tuple[Partial[TC], Partial[TC1], Partial[TC2]]]):
157
157
  table1: Type[TC]
158
158
  table2: Type[TC1]
159
159
  table3: Type[TC2]
160
160
  cursor: Cursor
161
161
  selection: Sequence[PropSelect[TC, Any] | PropSelect[TC1, Any] | PropSelect[TC2, Any]]
162
162
 
163
- def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2]]:
163
+ def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2]]:
164
164
  data1: Dict[str, Any] = {}
165
165
  data2: Dict[str, Any] = {}
166
166
  data3: Dict[str, Any] = {}
@@ -171,20 +171,20 @@ class PsycoPgJoinResponse3(Generic[TC, TC1, TC2], SqlResponse[Tuple[PartialModel
171
171
  data2[prop.label] = sql_record[i]
172
172
  else:
173
173
  data3[prop.label] = sql_record[i]
174
- return PartialModel(self.table1, **data1), PartialModel(self.table2, **data2), PartialModel(self.table3, **data3)
174
+ return Partial(self.table1, **data1), Partial(self.table2, **data2), Partial(self.table3, **data3)
175
175
 
176
- def fetchone(self) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2]] | None:
176
+ def fetchone(self) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2]] | None:
177
177
  result = self.cursor.fetchone()
178
178
  if result is not None:
179
179
  return self.__make_record(result)
180
180
  return None
181
181
 
182
- def stream(self) -> Iterator[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2]]]:
182
+ def stream(self) -> Iterator[Tuple[Partial[TC], Partial[TC1], Partial[TC2]]]:
183
183
  for row in self.cursor:
184
184
  yield self.__make_record(row)
185
185
 
186
186
  @dataclass
187
- class PsycoPgComputedResponse3(Generic[TC, TC1, TC2], SqlResponse[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], ComputedResult]]):
187
+ class PsycoPgComputedResponse3(Generic[TC, TC1, TC2], SqlResponse[Tuple[Partial[TC], Partial[TC1], Partial[TC2], ComputedResult]]):
188
188
  table1: Type[TC]
189
189
  table2: Type[TC1]
190
190
  table3: Type[TC2]
@@ -192,7 +192,7 @@ class PsycoPgComputedResponse3(Generic[TC, TC1, TC2], SqlResponse[Tuple[PartialM
192
192
  selection: Sequence[PropSelect[TC, Any] | PropSelect[TC1, Any] | PropSelect[TC2, Any]]
193
193
  computed: Sequence[Computed[TC, Any] | Computed[TC1, Any] | Computed[TC2, Any]]
194
194
 
195
- def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], ComputedResult]:
195
+ def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2], ComputedResult]:
196
196
  data1: Dict[str, Any] = {}
197
197
  data2: Dict[str, Any] = {}
198
198
  data3: Dict[str, Any] = {}
@@ -203,20 +203,20 @@ class PsycoPgComputedResponse3(Generic[TC, TC1, TC2], SqlResponse[Tuple[PartialM
203
203
  data2[prop.label] = sql_record[i]
204
204
  else:
205
205
  data3[prop.label] = sql_record[i]
206
- return PartialModel(self.table1, **data1), PartialModel(self.table2, **data2), PartialModel(self.table3, **data3), _computed_record(self.computed, sql_record, len(self.selection))
206
+ return Partial(self.table1, **data1), Partial(self.table2, **data2), Partial(self.table3, **data3), _computed_record(self.computed, sql_record, len(self.selection))
207
207
 
208
- def fetchone(self) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], ComputedResult] | None:
208
+ def fetchone(self) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2], ComputedResult] | None:
209
209
  result = self.cursor.fetchone()
210
210
  if result is not None:
211
211
  return self.__make_record(result)
212
212
  return None
213
213
 
214
- def stream(self) -> Iterator[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], ComputedResult]]:
214
+ def stream(self) -> Iterator[Tuple[Partial[TC], Partial[TC1], Partial[TC2], ComputedResult]]:
215
215
  for row in self.cursor:
216
216
  yield self.__make_record(row)
217
217
 
218
218
  @dataclass
219
- class PsycoPgJoinResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3]]]):
219
+ class PsycoPgJoinResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3]]]):
220
220
  table1: Type[TC]
221
221
  table2: Type[TC1]
222
222
  table3: Type[TC2]
@@ -224,7 +224,7 @@ class PsycoPgJoinResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[Partial
224
224
  cursor: Cursor
225
225
  selection: Sequence[PropSelect[TC, Any] | PropSelect[TC1, Any] | PropSelect[TC2, Any] | PropSelect[TC3, Any]]
226
226
 
227
- def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3]]:
227
+ def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3]]:
228
228
  data1: Dict[str, Any] = {}
229
229
  data2: Dict[str, Any] = {}
230
230
  data3: Dict[str, Any] = {}
@@ -238,20 +238,20 @@ class PsycoPgJoinResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[Partial
238
238
  data3[prop.label] = sql_record[i]
239
239
  else:
240
240
  data4[prop.label] = sql_record[i]
241
- return PartialModel(self.table1, **data1), PartialModel(self.table2, **data2), PartialModel(self.table3, **data3), PartialModel(self.table4, **data4)
241
+ return Partial(self.table1, **data1), Partial(self.table2, **data2), Partial(self.table3, **data3), Partial(self.table4, **data4)
242
242
 
243
- def fetchone(self) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3]] | None:
243
+ def fetchone(self) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3]] | None:
244
244
  result = self.cursor.fetchone()
245
245
  if result is not None:
246
246
  return self.__make_record(result)
247
247
  return None
248
248
 
249
- def stream(self) -> Iterator[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3]]]:
249
+ def stream(self) -> Iterator[Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3]]]:
250
250
  for row in self.cursor:
251
251
  yield self.__make_record(row)
252
252
 
253
253
  @dataclass
254
- class PsycoPgComputedResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3], ComputedResult]]):
254
+ class PsycoPgComputedResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3], ComputedResult]]):
255
255
  table1: Type[TC]
256
256
  table2: Type[TC1]
257
257
  table3: Type[TC2]
@@ -260,7 +260,7 @@ class PsycoPgComputedResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[Par
260
260
  selection: Sequence[PropSelect[TC, Any] | PropSelect[TC1, Any] | PropSelect[TC2, Any] | PropSelect[TC3, Any]]
261
261
  computed: Sequence[Computed[TC, Any] | Computed[TC1, Any] | Computed[TC2, Any] | Computed[TC3, Any]]
262
262
 
263
- def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3], ComputedResult]:
263
+ def __make_record(self, sql_record: Tuple[Any, ...]) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3], ComputedResult]:
264
264
  data1: Dict[str, Any] = {}
265
265
  data2: Dict[str, Any] = {}
266
266
  data3: Dict[str, Any] = {}
@@ -274,15 +274,15 @@ class PsycoPgComputedResponse4(Generic[TC, TC1, TC2, TC3], SqlResponse[Tuple[Par
274
274
  data3[prop.label] = sql_record[i]
275
275
  else:
276
276
  data4[prop.label] = sql_record[i]
277
- return PartialModel(self.table1, **data1), PartialModel(self.table2, **data2), PartialModel(self.table3, **data3), PartialModel(self.table4, **data4), _computed_record(self.computed, sql_record, len(self.selection))
277
+ return Partial(self.table1, **data1), Partial(self.table2, **data2), Partial(self.table3, **data3), Partial(self.table4, **data4), _computed_record(self.computed, sql_record, len(self.selection))
278
278
 
279
- def fetchone(self) -> Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3], ComputedResult] | None:
279
+ def fetchone(self) -> Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3], ComputedResult] | None:
280
280
  result = self.cursor.fetchone()
281
281
  if result is not None:
282
282
  return self.__make_record(result)
283
283
  return None
284
284
 
285
- def stream(self) -> Iterator[Tuple[PartialModel[TC], PartialModel[TC1], PartialModel[TC2], PartialModel[TC3], ComputedResult]]:
285
+ def stream(self) -> Iterator[Tuple[Partial[TC], Partial[TC1], Partial[TC2], Partial[TC3], ComputedResult]]:
286
286
  for row in self.cursor:
287
287
  yield self.__make_record(row)
288
288
 
@@ -313,7 +313,7 @@ class PsycoPgSqlTransaction(SqlTransaction):
313
313
  case ComputedQuery4():
314
314
  return cast(SqlResponse[R], PsycoPgComputedResponse4(query.table1, query.table2, query.table3, query.table4, self.cursor, query._resolved_selection(), query._computed))
315
315
  case Query1():
316
- # Query1[TC]'s R is always PartialModel[TC], which is exactly the caller's R here,
316
+ # Query1[TC]'s R is always Partial[TC], which is exactly the caller's R here,
317
317
  # but match narrowing can't invert R back to TC to prove that statically.
318
318
  return cast(SqlResponse[R], PsycoPgSqlResponse(query.table1, self.cursor, query._resolved_selection()))
319
319
  case Query2():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydoptic-sql
3
- Version: 0.0.2.post1.dev1
3
+ Version: 0.0.2.post1.dev2
4
4
  Summary: A type-safe SQL query builder built on pydoptic
5
5
  Author: John Hungerford
6
6
  License-Expression: MIT
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.0.2",
3
+ "distance": 2,
4
+ "node": "g9a2420ef5de99bf2d4026d1af9ef469fad88bcab",
5
+ "dirty": false,
6
+ "branch": "main",
7
+ "node_date": "2026-09-07"
8
+ }
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "0.0.2",
3
- "distance": 1,
4
- "node": "ga0068181cb2d8dfd1b14469d4ad3bdc4cfd63617",
5
- "dirty": false,
6
- "branch": "main",
7
- "node_date": "2026-08-18"
8
- }