@@ -211,8 +211,14 @@ def simple_query_data(simple_table):
211211
212212@pytest .fixture (scope = "module" )
213213def complex_query_data (complex_table ):
214- presets = [dict ()] * 20
215- data = [datum for datum in [complex_model_data_generator (** i ) for i in presets ]]
214+ record_count = 500
215+ presets = [dict ()] * record_count
216+ accounts = [str (uuid4 ()) for i in range (4 )]
217+
218+ data = [
219+ complex_model_data_generator (account = accounts [i % 4 ], ** p )
220+ for i , p in enumerate (presets )
221+ ]
216222 for datum in data :
217223 ComplexKeyModel .parse_obj (datum ).save ()
218224 try :
@@ -234,6 +240,7 @@ def alias_query_data(alias_table):
234240 for datum in data :
235241 AliasKeyModel .delete (datum ["name" ])
236242
243+
237244@pytest .fixture (scope = "module" )
238245def nested_query_data (nested_table ):
239246 presets = [dict ()] * 5
@@ -249,7 +256,7 @@ def nested_query_data(nested_table):
249256
250257
251258@pytest .fixture (scope = "module" )
252- def nested_query_data_optional (nested_table ):
259+ def nested_query_data_empty_ticket (nested_table ):
253260 presets = [dict ()] * 5
254261 data = [datum for datum in [nested_model_data_generator (include_ticket = False , ** i ) for i in presets ]]
255262 for datum in data :
@@ -282,6 +289,14 @@ def test_query_with_hash_key_simple(dynamo, simple_query_data):
282289 assert res_data == {simple_query_data [0 ]["name" ]: simple_query_data [0 ]}
283290
284291
292+ def test_scan_errors_with_order (dynamo , simple_query_data ):
293+ data_by_timestamp = simple_query_data [:]
294+ data_by_timestamp .sort (key = lambda d : d ["timestamp" ])
295+ with pytest .raises (ConditionCheckFailed ,
296+ match = r"Scans do not support reverse order." ):
297+ SimpleKeyModel .query (order = 'desc' )
298+
299+
285300def test_query_errors_with_nonprimary_key_simple (dynamo , simple_query_data ):
286301 data_by_timestamp = simple_query_data [:]
287302 data_by_timestamp .sort (key = lambda d : d ["timestamp" ])
@@ -347,13 +362,55 @@ def test_query_with_hash_key_complex(dynamo, complex_query_data):
347362 res_data = {(m .account , m .sort_date_key ): m .dict () for m in res }
348363 assert res_data == {(record ["account" ], record ["sort_date_key" ]): record }
349364
350- # Check that it works regardless of order
365+ # Check that it works regardless of query attribute order
351366 res = ComplexKeyModel .query (
352367 Rule (f"sort_date_key == '{ record ['sort_date_key' ]} ' and account == '{ record ['account' ]} '" ))
353368 res_data = {(m .account , m .sort_date_key ): m .dict () for m in res }
354369 assert res_data == {(record ["account" ], record ["sort_date_key" ]): record }
355370
356371
372+ @pytest .mark .parametrize ('order' , ('asc' , 'desc' ))
373+ def test_ordered_query_with_hash_key_complex (dynamo , complex_query_data , order ):
374+ middle_record = complex_query_data [(len (complex_query_data )// 2 )]
375+ res = ComplexKeyModel .query (
376+ Rule (f"account == '{ middle_record ['account' ]} ' and sort_date_key >= '{ middle_record ['sort_date_key' ]} '" ),
377+ order = order
378+ )
379+ res_data = [(m .account , m .sort_date_key ) for m in res ]
380+ check_data = sorted ([
381+ (m ["account" ], m ["sort_date_key" ])
382+ for m in complex_query_data
383+ if m ["account" ] == middle_record ['account' ] and m ["sort_date_key" ] >= middle_record ['sort_date_key' ]
384+ ], reverse = order == 'desc' )
385+
386+ assert res_data == check_data
387+
388+
389+ @pytest .mark .parametrize ('order' , ('asc' , 'desc' ))
390+ def test_pagination_query_with_hash_key_complex (dynamo , complex_query_data , order ):
391+ page_size = 2
392+ middle_record = complex_query_data [(len (complex_query_data )// 2 )]
393+ query_rule = Rule (f"account == '{ middle_record ['account' ]} ' and sort_date_key >= '{ middle_record ['sort_date_key' ]} '" )
394+ res = ComplexKeyModel .query (query_rule , order = order , limit = page_size )
395+ res_data = [(m .account , m .sort_date_key ) for m in res ]
396+ check_data = sorted ([
397+ (m ["account" ], m ["sort_date_key" ])
398+ for m in complex_query_data
399+ if m ["account" ] == middle_record ['account' ] and m ["sort_date_key" ] >= middle_record ['sort_date_key' ]
400+ ], reverse = order == 'desc' )[:page_size ]
401+ assert res_data == check_data
402+ assert res .last_evaluated_key == check_data [- 1 ]
403+
404+ res = ComplexKeyModel .query (query_rule , order = order , limit = page_size , exclusive_start_key = res .last_evaluated_key )
405+ res_data = [(m .account , m .sort_date_key ) for m in res ]
406+ check_data = sorted ([
407+ (m ["account" ], m ["sort_date_key" ])
408+ for m in complex_query_data
409+ if m ["account" ] == middle_record ['account' ] and m ["sort_date_key" ] >= middle_record ['sort_date_key' ]
410+ ], reverse = order == 'desc' )[page_size :page_size * 2 ]
411+ assert res_data == check_data
412+
413+
357414def test_query_errors_with_nonprimary_key_complex (dynamo , complex_query_data ):
358415 data_by_expires = complex_query_data [:]
359416 data_by_expires .sort (key = lambda d : d ["expires" ])
@@ -381,15 +438,13 @@ def test_query_scan_complex(dynamo, complex_query_data):
381438
382439
383440def test_query_with_nested_model (dynamo , nested_query_data ):
384- data_by_expires = nested_model_data_generator ()
385- res = NestedModel .query (filter_expr = Rule (f"expires <= '{ data_by_expires ['expires' ]} '" ))
441+ res = NestedModel .query ()
386442 res_data = [m .ticket for m in res ]
387443 assert any (elem is not None for elem in res_data )
388444
389445
390- def test_query_with_nested_model_optional (dynamo , nested_query_data_optional ):
391- data_by_expires = nested_model_data_generator (include_ticket = False )
392- res = NestedModel .query (filter_expr = Rule (f"expires <= '{ data_by_expires ['expires' ]} '" ))
446+ def test_query_with_nested_model_optional (dynamo , nested_query_data_empty_ticket ):
447+ res = NestedModel .query ()
393448 res_data = [m .ticket for m in res ]
394449 assert any (elem is None for elem in res_data )
395450
@@ -404,6 +459,7 @@ def test_query_alias_save(dynamo):
404459 except Exception as e :
405460 raise pytest .fail ("Failed to save Alias model!" )
406461
462+
407463def test_get_alias_model_data (dynamo , alias_query_data ):
408464 data = alias_model_data_generator ()
409465 res = AliasKeyModel .get (alias_query_data [0 ]['name' ])
0 commit comments