Как обновить столбец DynamoDB значениями из фрейма данных pandas, используя ИДЕНТИФИКАТОР в качестве общего значения

#python #pandas #amazon-dynamodb #boto3

#python #pandas #amazon-dynamodb #boto3

Вопрос:

У меня есть таблица с именем returns-portal в DynamoDB, у меня также есть фрейм данных с двумя столбцами order_name и return_status.

Мне нужно обновить таблицу DynamoDB, столбец return_status со значениями в моем DF (df2), используя order_name в качестве идентификатора для обоих наборов данных, и order_name может появляться несколько раз в таблице DynamoDB, но только один раз в df2. Проблема, с которой я сталкиваюсь, заключается в том, что я действительно не понимаю, как это возможно. Я пытался сам что-то собрать, но это не сработает, см. Код ниже:

 import boto3
from boto3.dynamodb.conditions import Key
import json
import pyodbc
import pandas as pd
import numpy as np
import datetime
from func.excelfunction import *
from datetime import datetime as dt
from datetime import timedelta
import requests
import csv
import os
import math
from sql_server.sql_server import *

#Connect to ETL DB

df1 = run_sql_df('SET NOCOUNT ON; select distinct order_number, return_status from etl_db.dbo.shopify_returns_portal')
df1 = df1.astype({"order_number":"str","return_status":"str"})

filename = 'test_file.csv'

df1.to_csv(str(filename),index=False)

df2 = pd.read_csv('test_file.csv')
df2 = df2.astype({"order_number":"str","return_status":"str"})


#create update statement for DynamoDB

def update_status(order_number,return_status, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource("dynamodb",aws_access_key_id ="XXXXXXXXXXXX",aws_secret_access_key = "XXXXXXXXXXXXXXXXXX",region_name = "eu-west-1")

    table = dynamodb.Table('returns-portal')

    response = table.update_item(
        Key={
            'order_number': df2.order_number
        },
        UpdateExpression="set return_status =:r",
        ExpressionAttributeValues={
            ':r': df2.return_status
        },
        ReturnValues="UPDATED_NEW"
    )
    return response


if __name__ == '__main__':

    update_response = update_status(df2.order_number,df2.return_status)
    print("Update movie succeeded:")
    pprint(update_response, sort_dicts=False)
  

ошибка, которую я получаю, такова:

 TypeError: Unsupported type "<class 'pandas.core.series.Series'>" for value "0        25061198
1        25061184
2        14441634
3        14441639
4        25061205
5     26054929503
6        25061203
7        25061186
8        14441629
9        25061187
10       25061201
11       25061196
12       14441636
13       25061177
14       25061194
15       14441641
16       25061189
17       25061206
18       25061204
19       14441628
20       25061199
21       25061185
22       14441633
23       25061197
24       25061180
25       14441638
26       25061192
27       25061195
28       14441637
29       25061193
30       25061200
31       14441635
Name: order_number, dtype: object"
  

У меня есть сильное подозрение, что я делаю это совершенно неправильно, но я не могу найти в Интернете ничего о людях, использующих фрейм данных для обновления таблицы DynamoDB. Глядя на это, я чувствую, что вам, возможно, придется перебирать строки в DynamoDB, но я понятия не имею, так ли это или как это сделать.

Вся помощь приветствуется.

Комментарии:

1. Преобразуйте его в список словарей, используя метод to_dict в pandas. Затем выполните итерацию по этому списку и вызовите update для каждого элемента словаря.

Ответ №1:

Вы не перебираете список order_number или return_status, вы отправляете весь столбец (или серию).

Во-первых, не уверен, почему вы перечитываете csv в df2, просто используйте df1 повсюду — это одни и те же данные…

Чтобы получить списки для итерации, вы можете использовать zip или to_dict, как упоминалось. Вот пример zip. Он выдает список кортежей.

 onum_status_pair_list = list(zip(df1['order_number'], df1['return_status']))
  

затем вы хотите повторить это. Обновление вашего кода:

 def update_status(order_number,return_status, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource("dynamodb",aws_access_key_id ="XXXXXXXXXXXX",aws_secret_access_key = "XXXXXXXXXXXXXXXXXX",region_name = "eu-west-1")

    table = dynamodb.Table('returns-portal')

    response = table.update_item(
        Key={
            'order_number': order_number
        },
        UpdateExpression="set return_status =:r",
        ExpressionAttributeValues={
            ':r': return_status
        },
        ReturnValues="UPDATED_NEW"
    )
    return response


if __name__ == '__main__':
    # note use of parenthesis to iterate list of tuples
    for (onum, stat) in onum_status_pair_list:
        update_response = update_status(onum,stat)
        print("Update movie succeeded:")
        pprint(update_response, sort_dicts=False)
  

Если у вас возникнут проблемы, напишите мне записку. У меня нет способа проверить это…