#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)
Если у вас возникнут проблемы, напишите мне записку. У меня нет способа проверить это…