1616class PostgresListAdapter (SQLTypeAdapter ):
1717 """
1818 Adapts Python list to PostgreSQL array types.
19-
19+
2020 This adapter does not perform any conversion - psycopg handles
2121 Python lists natively for PostgreSQL array types.
2222 """
@@ -37,11 +37,42 @@ def from_database(self, value: Any, target_type: Type, options: Optional[Dict[st
3737 return value
3838 raise TypeError (f"Cannot convert { type (value ).__name__ } to list" )
3939
40+ def to_database_batch (self , values : List [Any ], target_type : Type ,
41+ options : Optional [Dict [str , Any ]] = None ) -> List [Any ]:
42+ """Optimized batch conversion - psycopg handles lists natively.
43+
44+ No per-element processing needed, just pass through.
45+ This avoids the overhead of calling to_database() for each element.
46+
47+ Args:
48+ values: List of values to convert
49+ target_type: Target type (not used for lists)
50+ options: Optional conversion options
51+
52+ Returns:
53+ The same list, psycopg handles conversion internally
54+ """
55+ return values
56+
57+ def from_database_batch (self , values : List [Any ], target_type : Type ,
58+ options : Optional [Dict [str , Any ]] = None ) -> List [Any ]:
59+ """Optimized batch conversion from database.
60+
61+ Args:
62+ values: List of values from database
63+ target_type: Target Python type
64+ options: Optional conversion options
65+
66+ Returns:
67+ The same list, psycopg already returns Python lists
68+ """
69+ return values
70+
4071
4172class PostgresJSONBAdapter (SQLTypeAdapter ):
4273 """
4374 Adapts Python dict to PostgreSQL JSONB and vice-versa.
44-
75+
4576 Note: psycopg automatically serializes/deserializes JSON, so dict <-> JSON.
4677 When reading from DB, psycopg returns dict. When target type is str,
4778 we need to serialize back to JSON string.
@@ -55,7 +86,8 @@ def to_database(self, value: Union[dict, list], target_type: Type, options: Opti
5586 return None
5687 return Jsonb (value )
5788
58- def from_database (self , value : Any , target_type : Type , options : Optional [Dict [str , Any ]] = None ) -> Union [dict , list ]:
89+ def from_database (self , value : Any , target_type : Type ,
90+ options : Optional [Dict [str , Any ]] = None ) -> Union [dict , list ]:
5991 if value is None :
6092 return None
6193 # For string target type, serialize dict/list back to JSON string
@@ -73,6 +105,55 @@ def from_database(self, value: Any, target_type: Type, options: Optional[Dict[st
73105 # In case it's a string representation
74106 return json .loads (value )
75107
108+ def to_database_batch (self , values : List [Any ], target_type : Type ,
109+ options : Optional [Dict [str , Any ]] = None ) -> List [Any ]:
110+ """Optimized batch JSON conversion to database format.
111+
112+ Creates Jsonb wrappers for all values in a single pass,
113+ reducing function call overhead compared to individual calls.
114+
115+ Args:
116+ values: List of values to convert
117+ target_type: Target type (Jsonb)
118+ options: Optional conversion options
119+
120+ Returns:
121+ List of Jsonb-wrapped values
122+ """
123+ result = []
124+ for value in values :
125+ if value is None :
126+ result .append (None )
127+ else :
128+ result .append (Jsonb (value ))
129+ return result
130+
131+ def from_database_batch (self , values : List [Any ], target_type : Type ,
132+ options : Optional [Dict [str , Any ]] = None ) -> List [Any ]:
133+ """Optimized batch JSON deserialization from database.
134+
135+ Args:
136+ values: List of values from database
137+ target_type: Target Python type (dict, list, or str)
138+ options: Optional conversion options
139+
140+ Returns:
141+ List of converted values
142+ """
143+ result = []
144+ for value in values :
145+ if value is None :
146+ result .append (None )
147+ elif target_type is str :
148+ if isinstance (value , (dict , list )):
149+ result .append (json .dumps (value ))
150+ else :
151+ result .append (value )
152+ else :
153+ # For dict/list target types, return as-is
154+ result .append (value )
155+ return result
156+
76157
77158
78159class PostgresNetworkAddressAdapter (SQLTypeAdapter ):
@@ -111,6 +192,55 @@ def from_database(self, value: Any, target_type: Type, options: Optional[Dict[st
111192 except (ImportError , ValueError ):
112193 return value
113194
195+ def to_database_batch (self , values : List [Any ], target_type : Type ,
196+ options : Optional [Dict [str , Any ]] = None ) -> List [Any ]:
197+ """Optimized batch network address conversion.
198+
199+ Converts all values to strings in a single pass.
200+
201+ Args:
202+ values: List of values to convert
203+ target_type: Target type
204+ options: Optional conversion options
205+
206+ Returns:
207+ List of string representations
208+ """
209+ result = []
210+ for value in values :
211+ if value is None :
212+ result .append (None )
213+ else :
214+ result .append (str (value ))
215+ return result
216+
217+ def from_database_batch (self , values : List [Any ], target_type : Type ,
218+ options : Optional [Dict [str , Any ]] = None ) -> List [Any ]:
219+ """Optimized batch network address parsing from database.
220+
221+ Args:
222+ values: List of string values from database
223+ target_type: Target Python type
224+ options: Optional conversion options
225+
226+ Returns:
227+ List of ipaddress objects or strings
228+ """
229+ import ipaddress
230+ result = []
231+ for value in values :
232+ if value is None :
233+ result .append (None )
234+ else :
235+ try :
236+ result .append (ipaddress .ip_address (value ))
237+ except (ImportError , ValueError ):
238+ try :
239+ result .append (ipaddress .ip_network (value ))
240+ except (ImportError , ValueError ):
241+ result .append (value )
242+ return result
243+
114244
115245class PostgresEnumAdapter (SQLTypeAdapter ):
116246 """PostgreSQL ENUM type adapter.
0 commit comments