Python: миграция MongoDB в DynamoDB - ошибка с плавающей точкой - PullRequest
0 голосов
/ 08 июня 2018

Я начинаю использовать Python в своей повседневной работе, я нашел проблему, которую не могу решить.С помощью этого сценария, изменяя только имя коллекции (MongoDB) и имя таблицы (DynamoDB), весь процесс очень хорошо выполняется в других коллекциях.

В одной коллекции (пример ниже) сценарийне работает так хорошо, потому что в коллекции есть плавающие данные, такие как данные геолокации

import sys

# Mongo
import pprint
from pymongo import MongoClient
Client = MongoClient('mongodb://localhost:27017/')
db = Client["developer"]
collection = db["geolocation"]

# Dynamo
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('geolocation')


# migrate
count = 0
with table.batch_writer() as batch:
    for migrate in collection.find():
        del migrate['__v']
        del migrate['_id']

        batch.put_item(Item= migrate)

        # To show process
        count += 1
        print(str(collection.count()) + '::' + str(count))

Произошла ошибка: типы с плавающей точкой не поддерживаются.Вместо этого используйте десятичные типы .

Мне нужно помочь создать def, который сканирует объект и заменяет значение с плавающей запятой на десятичные.Кто-нибудь может мне помочь?

Ответы [ 2 ]

0 голосов
/ 04 января 2019

DynamoDB ожидает десятичный формат для чисел с плавающей запятой, когда элемент загружается через boto3.

Вам необходимо заменить все значения с плавающей запятой на десятичный в словаре из MongoDB.

Сначала преобразуйте словарь Python обратно в JSON

import json
migrate_json = json.dumps(migrate)

Затем выполните синтаксический анализ JSON назад.в словарь Python с плавающей точкой, хранящейся в десятичном формате.

from decimal import Decimal
migrate = json.loads(migrate_json, parse_float=Decimal)

Теперь загрузка будет работать

batch.put_item(Item=migrate)
0 голосов
/ 08 июня 2018

Это определение решает проблему

def replace_float(obj):
    if isinstance(obj, list):
        for i in xrange(len(obj)):
            obj[i] = replace_float(obj[i])
        return obj
    elif isinstance(obj, dict):
        for k in obj.iterkeys():
            obj[k] = replace_float(obj[k])
        return obj
    elif isinstance(obj, float):
        if obj % 1 == 0:
            return int(obj)
        else:
            return Decimal(str(obj))
    else:
        return obj

Итак, замените ...

newItem=replace_float(migrate)
batch.put_item(Item=newItem)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...