DynamoDb, невозможно динамически обновить элемент с помощью выражений - PullRequest
0 голосов
/ 04 февраля 2020

Я пытаюсь обновить таблицу Dynamo, используя выражение, я пытаюсь генерировать ключи динамически. Похоже, проблема заключается в том, что если в ключе есть место, выражения не оцениваются должным образом.

В моей реализации обновления:

        update_expression = 'SET {}'.format(','.join(f'#{p}=:{p}' for p in row_as_dict))
        expression_attribute_values = {f':{p}': v for p, v in row_as_dict.items()}
        expression_attribute_names = {f'#{p}': p for p in row_as_dict}

        if result_set.get('Item') and result_set.get('Item').get(primary_key):
            TABLE.update_item(
                Key={
                    primary_key: row_as_dict[primary_key],
                    sort_key: row_as_dict[sort_key]
                },
                UpdateExpression=update_expression,
                ExpressionAttributeValues=expression_attribute_values,
                ExpressionAttributeNames=expression_attribute_names
            )

, если я печатаю значения для update_expression и expression_attribute_values ​​и expression_attribute_names я получаю следующий вывод. update_expression

SET #Ref No=:Ref No,#FT/Hot=:FT/Hot,#Irfan watch List=:Irfan watch List,#F.Soahil watchList=:F.Soahil watchList,#HR Responible=:HR Responible,#Pipeline(Adv/Ref)=:Pipeline
(Adv/Ref),#Source=:Source,#Date Submitted=:Date Submitted,#Name=:Name,#Candidate Location=:Candidate Location,#Tech =:Tech ,#Current Company=:Current Company,#Exp=:Exp,#Position being considered for=:Position being considered for,#Proj. / Gen Hiring=:Proj. / Gen Hiring,#Comments / Latest Status / Next Step=:Comments / Latest Status / Next Step,#Status=:Status,#hiring status=:hiring status,#Link to Lever=:Link to Lever,#LinkedIn Link / Resume=:LinkedIn Link / Resume,#Interview Feedback Google Doc=:Interview Feedback Google Doc,#Email=:Email

expression_attribute_values ​​

{':Ref No': '1', ':FT/Hot': 'NaN', ':Irfan watch List': 'NaN', ':F.Soahil watchList': 'NaN', ':HR Responible': 'Khurram', ':Pipeline\r\n(Adv/Ref)': 'Referred', ':Source': 'Usman Khan', ':Date Submitted': '17-Dec', ':Name': 'Asif Mahmood Mughal Zain', ':Candidate Location': 'ISL', ':Tech ': 'Spark. Hadoop\r\nSQL, Big Data', ':Current Company': 'Zain Telecom', ':Exp': '18+', ':Position being considered for': 'Senior SA', ':Proj. / Gen Hiring': 'General', ':Comments / Latest Status / Next Step': 'Muhammaf Naseer      Recommneded\r\nAdeel Ashraf                Recommended\r\nFaheem Khan              Recommended\r\n\r\nAccepted offer.will join on 6 jan', ':Status': 'Joined', ':hiring status': 'Hired', ':Link to Lever': 'Link to Lever', ':LinkedIn Link / Resume': 'Asif Mehmood Mughal', ':Interview Feedback Google Doc': 'Link to Feedback', ':Email': 'some_email1@test.com'}

expression_attribute_names

{'#Ref No': 'Ref No', '#FT/Hot': 'FT/Hot', '#Irfan watch List': 'Irfan watch List', '#F.Soahil watchList': 'F.Soahil watchList', '#HR Responible': 'HR Responible', '#Pipeline\r\n(Adv/Ref)': 'Pipeline\r\n(Adv/Ref)', '#Source': 'Source', '#Date Submitted': 'Date Submitted', '#Name': 'Name', '#Candidate Location': 'Candidate Location', '#Tech ': 'Tech ', '#Current Company': 'Current Company', '#Exp': 'Exp', '#Position being considered for': 'Position being considered for', '#Proj. / Gen Hiring': 'Proj. / Gen Hiring', '#Comments / Latest Status / Next Step': 'Comments / Latest Status / Next Step', '#Status': 'Status', '#hiring status': 'hiring status', '#Link to Lever': 'Link to Lever', '#LinkedIn Link / Resume': 'LinkedIn Link / Resume', '#Interview Feedback Google Doc': 'Interview Feedback Google Doc', '#Email': 'Email'}

Ошибка сгенерировано

Произошла ошибка (ValidationException) при вызове операции UpdateItem: ExpressionAttributeValues ​​содержит недопустимый ключ: синтаксическая ошибка; клавиша: ": статус найма"

Ответы [ 2 ]

1 голос
/ 04 февраля 2020

Вы не можете иметь пробелы в своих ключах / значениях атрибута в выражении. Так что :hiring status должно быть что-то вроде :hiring_status.

0 голосов
/ 06 февраля 2020

Go Dynamof!

Возможно, вас заинтересует dynamicof . Это библиотека, предназначенная для того, чтобы делать именно то, что вы пытаетесь сделать. По крайней мере, вы можете взять пик и проверить, как он обрабатывает динамически создавая все выражения.

Я предлагаю вам взглянуть на модуль args . У него есть функции, которые делают то, что вы пытаетесь сделать. Модуль args получает некоторую помощь от другого модуля (построителя запросов) в dynamof, который отвечает за некоторую предварительную обработку аргументов всего действия, поэтому функции модуля args упрощают использование и анализируют RequestTree объект.

Ответ ...

Я бы просто использовал dynamof - но я пристрастен. Если вы хотите написать это самостоятельно, вот небольшой пример того, как это было сделано прямо из dynamof.

def UpdateExpression(request: RequestTree):
    def expression(attr):
        if attr.func is not None:
            return attr.func.expression(attr)
        return f'{attr.alias} = {attr.key}'
    key_expressions = [expression(key) for key in request.attributes.values]
    key_expression = ', '.join(key_expressions)
    return f'SET {key_expression}'

ПРИМЕЧАНИЕ: attr.alias это то, что используется для обработки особых случаев имен - как пробелы. Он установлен в модуле построения запросов , упомянутом выше.

отказ от ответственности: я написал Dynamof

...