66
77import docker
88from botocore .exceptions import ClientError
9- from pydantic import BaseModel as PydanticBaseModel , Field , root_validator , ValidationError
9+ from pydantic import model_validator , BaseModel as PydanticBaseModel , Field , ValidationError
1010from pydanticrud import BaseModel , DynamoDbBackend , ConditionCheckFailed
1111import pytest
1212from pydanticrud .exceptions import DoesNotExist
@@ -30,11 +30,11 @@ class SimpleKeyModel(BaseModel):
3030 expires : datetime
3131 sigfig : Decimal
3232 enabled : bool
33- data : Dict [int , int ] = None
33+ data : Dict [int , int ] = {}
3434 items : List [int ]
3535 hash : UUID
3636
37- class Config :
37+ class db_config :
3838 title = "ModelTitle123"
3939 hash_key = "name"
4040 ttl = "expires"
@@ -49,13 +49,14 @@ class AliasKeyModel(BaseModel):
4949 name : str
5050 type_ : str = Field (alias = "type" )
5151
52- @root_validator (pre = True )
52+ @model_validator (mode = "before" )
53+ @classmethod
5354 def type_from_typ (cls , values ):
5455 if 'typ' in values :
5556 values ['type' ] = values .pop ('typ' )
5657 return values
5758
58- class Config :
59+ class db_config :
5960 title = "AliasTitle123"
6061 hash_key = "name"
6162 backend = DynamoDbBackend
@@ -71,7 +72,7 @@ class ComplexKeyModel(BaseModel):
7172 thread_id : str
7273 body : str = "some random string"
7374
74- class Config :
75+ class db_config :
7576 title = "ComplexModelTitle123"
7677 hash_key = "account"
7778 range_key = "sort_date_key"
@@ -101,14 +102,13 @@ class NestedModel(BaseModel):
101102 ticket : Optional [Ticket ]
102103 other : Union [Ticket , SomethingElse ]
103104
104- class Config :
105+ class db_config :
105106 title = "NestedModelTitle123"
106107 hash_key = "account"
107108 range_key = "sort_date_key"
108109 backend = DynamoDbBackend
109110 endpoint = "http://localhost:18002"
110111
111-
112112def alias_model_data_generator (** kwargs ):
113113 data = dict (
114114 id = random .randint (0 , 100000 ),
@@ -231,7 +231,7 @@ def simple_query_data(simple_table):
231231 data = [datum for datum in [simple_model_data_generator (** i ) for i in presets ]]
232232 del data [0 ]["data" ] # We need to have no data to ensure that default values work
233233 for datum in data :
234- SimpleKeyModel .parse_obj (datum ).save ()
234+ SimpleKeyModel .model_validate (datum ).save ()
235235 try :
236236 yield data
237237 finally :
@@ -250,20 +250,20 @@ def complex_query_data(complex_table):
250250 for i , p in enumerate (presets )
251251 ]
252252 for datum in data :
253- ComplexKeyModel .parse_obj (datum ).save ()
253+ ComplexKeyModel .model_validate (datum ).save ()
254254 try :
255255 yield data
256256 finally :
257257 for datum in data :
258- ComplexKeyModel .delete ((datum [ComplexKeyModel .Config .hash_key ], datum [ComplexKeyModel .Config . range_key ]))
258+ ComplexKeyModel .delete ((datum [ComplexKeyModel .db_config .hash_key ], datum [getattr ( ComplexKeyModel .db_config , " range_key" ) ]))
259259
260260
261261@pytest .fixture (scope = "module" )
262262def alias_query_data (alias_table ):
263263 presets = [dict (name = "Jerry" ), dict (name = "Hermione" ), dict (), dict (), dict ()]
264264 data = [datum for datum in [alias_model_data_generator (** i ) for i in presets ]]
265265 for datum in data :
266- AliasKeyModel .parse_obj (datum ).save ()
266+ AliasKeyModel .model_validate (datum ).save ()
267267 try :
268268 yield data
269269 finally :
@@ -276,35 +276,35 @@ def nested_query_data(nested_table):
276276 presets = [dict ()] * 5
277277 data = [datum for datum in [nested_model_data_generator (** i ) for i in presets ]]
278278 for datum in data :
279- nested_datum = NestedModel .parse_obj (datum )
279+ nested_datum = NestedModel .model_validate (datum )
280280 nested_datum .save ()
281281 try :
282282 yield data
283283 finally :
284284 for datum in data :
285- NestedModel .delete ((datum [NestedModel .Config .hash_key ], datum [NestedModel .Config .range_key ]))
285+ NestedModel .delete ((datum [NestedModel .db_config .hash_key ], datum [NestedModel .db_config .range_key ]))
286286
287287
288288@pytest .fixture
289289def nested_query_data_empty_ticket (nested_table ):
290290 presets = [dict ()] * 5
291291 data = [datum for datum in [nested_model_data_generator (include_ticket = False , ** i ) for i in presets ]]
292292 for datum in data :
293- NestedModel .parse_obj (datum ).save ()
293+ NestedModel .model_validate (datum ).save ()
294294 try :
295295 yield data
296296 finally :
297297 for datum in data :
298- NestedModel .delete ((datum [NestedModel .Config .hash_key ], datum [NestedModel .Config .range_key ]))
298+ NestedModel .delete ((datum [NestedModel .db_config .hash_key ], datum [NestedModel .db_config .range_key ]))
299299
300300
301301def test_save_get_delete_simple (dynamo , simple_table ):
302302 data = simple_model_data_generator ()
303- a = SimpleKeyModel .parse_obj (data )
303+ a = SimpleKeyModel .model_validate (data )
304304 a .save ()
305305 try :
306306 b = SimpleKeyModel .get (data ["name" ])
307- assert b .dict () == a .dict ()
307+ assert b .dict () == a .model_dump ()
308308 finally :
309309 SimpleKeyModel .delete (data ["name" ])
310310
@@ -330,7 +330,7 @@ def test_save_ttl_field_is_float(dynamo, simple_query_data):
330330def test_query_with_hash_key_simple (dynamo , simple_query_data ):
331331 res = SimpleKeyModel .query (Rule (f"name == '{ simple_query_data [0 ]['name' ]} '" ))
332332 res_data = {m .name : m .dict () for m in res }
333- simple_query_data [0 ]["data" ] = None # This is a default value and should be populated as such
333+ simple_query_data [0 ]["data" ] = {} # This is a default value and should be populated as such
334334 assert res_data == {simple_query_data [0 ]["name" ]: simple_query_data [0 ]}
335335
336336
@@ -383,11 +383,11 @@ def test_query_scan_contains_simple(dynamo, simple_query_data):
383383
384384def test_save_get_delete_complex (dynamo , complex_table ):
385385 data = complex_model_data_generator ()
386- a = ComplexKeyModel .parse_obj (data )
386+ a = ComplexKeyModel .model_validate (data )
387387 a .save ()
388388 try :
389389 b = ComplexKeyModel .get ((data ["account" ], data ["sort_date_key" ]))
390- assert b .dict () == a .dict ()
390+ assert b .dict () == a .model_dump ()
391391 finally :
392392 ComplexKeyModel .delete ((data ["account" ], data ["sort_date_key" ]))
393393
@@ -528,7 +528,7 @@ def test_query_alias_save(dynamo):
528528 AliasKeyModel .initialize ()
529529 try :
530530 for datum in data :
531- AliasKeyModel .parse_obj (datum ).save ()
531+ AliasKeyModel .model_validate (datum ).save ()
532532 except Exception as e :
533533 raise pytest .fail ("Failed to save Alias model!" )
534534
@@ -567,7 +567,7 @@ def test_alias_model_validator_ingest(dynamo):
567567
568568def test_batch_write (dynamo , complex_table ):
569569 response = {"UnprocessedItems" : {}}
570- data = [ComplexKeyModel .parse_obj (complex_model_data_generator ()) for x in range (0 , 10 )]
570+ data = [ComplexKeyModel .model_validate (complex_model_data_generator ()) for x in range (0 , 10 )]
571571 un_proc = ComplexKeyModel .batch_save (data )
572572 assert un_proc == response ["UnprocessedItems" ]
573573 res_get = ComplexKeyModel .get ((data [0 ].account , data [0 ].sort_date_key ))
@@ -581,7 +581,7 @@ def test_batch_write(dynamo, complex_table):
581581
582582def test_message_batch_write_client_exception (dynamo , complex_table ):
583583 data = [
584- ComplexKeyModel .parse_obj (complex_model_data_generator (body = "some big string" * 10000 ))
584+ ComplexKeyModel .model_validate (complex_model_data_generator (body = "some big string" * 10000 ))
585585 for x in range (0 , 2 )
586586 ]
587587 with pytest .raises (ClientError ) as exc :
0 commit comments