1212from botocore .exceptions import ClientError
1313from copy import copy
1414
15-
1615from marshmallow import ValidationError
1716
1817from .. import dynamo_db
2221fishfry_table = dynamo_db .tables ['FishFryDB' ]
2322fishfry_stats = dynamo_db .tables ['FishFryStats' ]
2423
24+ class DecimalEncoder (json .JSONEncoder ):
25+ """use to convert any DynamoDB items stored as Decimal objects to numbers.
26+ """
27+
28+ def default (self , o ):
29+ if isinstance (o , decimal .Decimal ):
30+ return float (o )
31+ return super (DecimalEncoder , self ).default (o )
2532
2633def decimal_decoder (json_obj ):
2734 """convert any floats in a dictionary (loaded from a json) to Decimal type.
2835 This is required in order to load data to DynamoDB.
2936 """
3037 return json .loads (json .dumps (json_obj ), parse_float = decimal .Decimal )
3138
39+ def decimal_encoder (json_obj ):
40+ return json .loads (json .dumps (json_obj , cls = DecimalEncoder ))
3241
33- class DecimalEncoder (json .JSONEncoder ):
34- """use to convert any DynamoDB items stored as Decimal objects to numbers.
42+
43+ def _paginated_scan (ddb_table ):
44+ """performs a paginated scan of the DynamoDB table
3545 """
46+
47+ response = ddb_table .scan ()
48+ data = response ['Items' ]
49+ print (len (data ))
3650
37- def default (self , o ):
38- if isinstance (o , decimal .Decimal ):
39- return float (o )
40- return super (DecimalEncoder , self ).default (o )
51+ while response .get ('LastEvaluatedKey' ):
52+ response = ddb_table .scan (ExclusiveStartKey = response ['LastEvaluatedKey' ])
53+ addl_data = response ['Items' ]
54+ print (len (addl_data ))
55+ data .extend (addl_data )
56+
57+ return {'Items' : data , 'Count' : len (data )}
58+
59+ def retrieve_all_records (ddb_table ):
60+ """ query the DB and decode
61+ """
62+
63+ return json .loads (
64+ json .dumps (
65+ _paginated_scan (ddb_table ),
66+ cls = DecimalEncoder
67+ )
68+ )
4169
70+ def is_not_blank (s ):
71+ return bool (s and s .strip ())
4272
4373def replace_emptry_strings (a_dict ):
4474 """use to convert empty strings to None values; DynamoDB doesn't like
4575 empty strings
4676 """
4777 for k , v in a_dict .items ():
4878 if not isinstance (v , dict ):
49- if v == "" :
50- a_dict [k ] = None
79+ if isinstance (v , str ):
80+ if not is_not_blank (v ):
81+ a_dict [k ] = None
5182 else :
5283 replace_emptry_strings (v )
5384
@@ -62,11 +93,11 @@ def get_all_fishfries(published=None, validated=None, has_geom=True):
6293 :type validated: bool, optional
6394 :param has_geom: [description], defaults to True
6495 :type has_geom: bool, optional
65-
96+
6697 """
6798
6899 # this effectively returns the "features" array of a GeoJSON Feature Collection
69- response = fishfry_table . scan ( )
100+ response = retrieve_all_records ( fishfry_table )
70101 if response ['Count' ] > 0 :
71102 # list of features
72103 features = response ["Items" ]
0 commit comments