11"""Synchronous Model objects."""
22
3- from typing import Any , Dict , List
3+ from typing import Any , Dict , List , Type
44from uuid import UUID
55
6+ from psycopg2 .extras import RealDictRow
7+
68from db_wrapper .client import SyncClient
79from .base import (
8- ensure_exactly_one ,
910 T ,
1011 CreateABC ,
12+ DeleteABC ,
1113 ReadABC ,
1214 UpdateABC ,
13- DeleteABC ,
1415 ModelABC ,
16+ ensure_exactly_one ,
1517 sql ,
1618)
1719
@@ -23,16 +25,22 @@ class SyncCreate(CreateABC[T]):
2325
2426 _client : SyncClient
2527
26- def __init__ (self , client : SyncClient , table : sql .Composable ) -> None :
27- super ().__init__ (table )
28+ def __init__ (
29+ self ,
30+ client : SyncClient ,
31+ table : sql .Composable ,
32+ return_constructor : Type [T ]
33+ ) -> None :
34+ super ().__init__ (table , return_constructor )
2835 self ._client = client
2936
3037 def one (self , item : T ) -> T :
3138 """Create one new record with a given item."""
32- result : List [T ] = self ._client .execute_and_return (
39+ query_result : List [RealDictRow ] = self ._client .execute_and_return (
3340 self ._query_one (item ))
41+ result : T = self ._return_constructor (** query_result [0 ])
3442
35- return result [ 0 ]
43+ return result
3644
3745
3846class SyncRead (ReadABC [T ]):
@@ -42,19 +50,26 @@ class SyncRead(ReadABC[T]):
4250
4351 _client : SyncClient
4452
45- def __init__ (self , client : SyncClient , table : sql .Composable ) -> None :
46- super ().__init__ (table )
53+ def __init__ (
54+ self ,
55+ client : SyncClient ,
56+ table : sql .Composable ,
57+ return_constructor : Type [T ]
58+ ) -> None :
59+ super ().__init__ (table , return_constructor )
4760 self ._client = client
4861
4962 def one_by_id (self , id_value : UUID ) -> T :
5063 """Read a row by it's id."""
51- result : List [T ] = self ._client .execute_and_return (
64+ query_result : List [RealDictRow ] = self ._client .execute_and_return (
5265 self ._query_one_by_id (id_value ))
5366
5467 # Should only return one item from DB
55- ensure_exactly_one (result )
68+ ensure_exactly_one (query_result )
5669
57- return result [0 ]
70+ result : T = self ._return_constructor (** query_result [0 ])
71+
72+ return result
5873
5974
6075class SyncUpdate (UpdateABC [T ]):
@@ -64,8 +79,13 @@ class SyncUpdate(UpdateABC[T]):
6479
6580 _client : SyncClient
6681
67- def __init__ (self , client : SyncClient , table : sql .Composable ) -> None :
68- super ().__init__ (table )
82+ def __init__ (
83+ self ,
84+ client : SyncClient ,
85+ table : sql .Composable ,
86+ return_constructor : Type [T ]
87+ ) -> None :
88+ super ().__init__ (table , return_constructor )
6989 self ._client = client
7090
7191 def one_by_id (self , id_value : str , changes : Dict [str , Any ]) -> T :
@@ -79,12 +99,14 @@ def one_by_id(self, id_value: str, changes: Dict[str, Any]) -> T:
7999 Returns:
80100 full value of row updated
81101 """
82- result : List [T ] = self ._client .execute_and_return (
102+ query_result : List [RealDictRow ] = self ._client .execute_and_return (
83103 self ._query_one_by_id (id_value , changes ))
84104
85- ensure_exactly_one (result )
105+ ensure_exactly_one (query_result )
106+
107+ result : T = self ._return_constructor (** query_result [0 ])
86108
87- return result [ 0 ]
109+ return result
88110
89111
90112class SyncDelete (DeleteABC [T ]):
@@ -94,19 +116,25 @@ class SyncDelete(DeleteABC[T]):
94116
95117 _client : SyncClient
96118
97- def __init__ (self , client : SyncClient , table : sql .Composable ) -> None :
98- super ().__init__ (table )
119+ def __init__ (
120+ self ,
121+ client : SyncClient ,
122+ table : sql .Composable ,
123+ return_constructor : Type [T ]
124+ ) -> None :
125+ super ().__init__ (table , return_constructor )
99126 self ._client = client
100127
101128 def one_by_id (self , id_value : str ) -> T :
102129 """Delete one record with matching ID."""
103- result : List [T ] = self ._client .execute_and_return (
130+ query_result : List [RealDictRow ] = self ._client .execute_and_return (
104131 self ._query_one_by_id (id_value ))
105132
106- # Should only return one item from DB
107- ensure_exactly_one (result )
133+ ensure_exactly_one (query_result )
134+
135+ result : T = self ._return_constructor (** query_result [0 ])
108136
109- return result [ 0 ]
137+ return result
110138
111139
112140class SyncModel (ModelABC [T ]):
@@ -128,13 +156,17 @@ def __init__(
128156 self ,
129157 client : SyncClient ,
130158 table : str ,
159+ return_constructor : Type [T ],
131160 ) -> None :
132161 super ().__init__ (client , table )
133162
134- self ._create = SyncCreate [T ](self .client , self .table )
135- self ._read = SyncRead [T ](self .client , self .table )
136- self ._update = SyncUpdate [T ](self .client , self .table )
137- self ._delete = SyncDelete [T ](self .client , self .table )
163+ self ._create = SyncCreate [T ](
164+ self .client , self .table , return_constructor )
165+ self ._read = SyncRead [T ](self .client , self .table , return_constructor )
166+ self ._update = SyncUpdate [T ](
167+ self .client , self .table , return_constructor )
168+ self ._delete = SyncDelete [T ](
169+ self .client , self .table , return_constructor )
138170
139171 @property
140172 def create (self ) -> SyncCreate [T ]:
0 commit comments