Skip to content

Instantly share code, notes, and snippets.

@shentonfreude
Created July 19, 2016 14:58
Show Gist options
  • Save shentonfreude/2cfb949ddee86b9c6e7b7195a0494f06 to your computer and use it in GitHub Desktop.
Save shentonfreude/2cfb949ddee86b9c6e7b7195a0494f06 to your computer and use it in GitHub Desktop.
DynamoDB update_item() is convoluted, requiring placeholders and name maps to avoid 572 reserved keywords; this seems a pretty concise approach to mapping a dict to names it will accept.
def asset_update(asset_id, state, extra={}):
asset = extra.copy()
asset.update({'dt': datetime.now().isoformat(),
'state': state})
# We need update_item placeholder and values like:
# UpdateExpression='SET dt = :dt, #state = :state' # 'state' is a reserved word
# ExpressionAttributeNames={'#state': 'state'} # proxy for reserved word 'state'
# ExpressionAttributeValues={':dt': datetime.now().isoformat(), ':state': 'uploaded'}
# We can't use "reserved words" like 'state' use EAN for *all* names,
# since we don't know _a priori_ the names that will be submitted.
ue = 'SET ' + ', '.join('#{} = :{}'.format(k, k) for k in asset.keys())
ean = {'#' + k: k for k in asset}
eav = {':' + k: v for k, v in asset.items()}
log.debug('asset_update ue={}'.format(ue))
log.debug('asset_update ean={}'.format(json.dumps(ean)))
log.debug('asset_update eav={}'.format(json.dumps(eav)))
try:
assetsdb.update_item(Key={'id': asset_id},
UpdateExpression=ue,
ExpressionAttributeNames=ean,
ExpressionAttributeValues=eav)
except (ClientError, BotoCoreError) as e:
raise Exception('[ServerError] update_item id={}: {}'.format(asset_id, e))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment