如何使用PyMongo从Python字典(到MongoDB)存储小数和日期

yuvru6vn  于 2023-10-21  发布在  Python
关注(0)|答案(2)|浏览(174)

下面是我用来测试的一段代码。我试图确定当你使用字典与JSON风格时会发生什么,以及当你使用变量时会发生什么。

from decimal import * 
    from pymongo import MongoClient
    
    my_int_a = "21"
    my_int_b = 21
    
   row_dict = {}
    row_dict['key'] = 'my string (default)'
    row_dict['myInteger'] = int(21)
    row_dict['myInteger2'] = 21
    row_dict['myInteger3'] = my_int_a
    row_dict['myInteger4'] = my_int_b
    # row_dict['myCurrencyDecimal'] = Decimal(25.97)
    row_dict['myCurrencyDouble'] = 25.97
    row_dict['myDateInsertedFmt'] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.000Z")
    row_dict['myDateInsertedNow'] = datetime.datetime.now()

    db_collection_test_datatypes.insert_one(row_dict)    db_collection_test_datatypes.insert_one(row_dict)
    
    
    json_dict = {
        'key': 'my json key',
        'myInteger': 21,
        'myCurrencyDouble': 25.97
    }
    db_collection_test_datatypes.insert_one(json_dict)

这是我在数据库中看到的:

{
    "_id": ObjectId("653052a351416c5223bbeee7"),
    "key": "my string (default)",
    "myInteger": NumberInt("21"),
    "myInteger2": NumberInt("21"),
    "myInteger3": "21",
    "myInteger4": NumberInt("21"),
    "myCurrencyDouble": 25.97,
    "myDateInsertedFmt": "2023-10-18T16:48:19.000Z",
    "myDateInsertedNow": ISODate("2023-10-18T16:48:19.411Z")
}    and 
    {
      "_id": ObjectId("65305109485c0394d26e8983"),
      "key": "my json key",
      "myInteger": NumberInt("21"),
      "myCurrencyDouble": 25.97
    }

注意:格式化日期上没有ISODate Package 。在某个地方,我看到上面是用于在MongoDB中存储日期的格式。所以如果我有一个日期,我需要把它加载到一个日期类型。(自从我第一次发布这个问题以来,我已经改变了好几次,它不是ISODATE)。
当我尝试使用decimal时(上面已经注解掉了),我得到了这个错误:
bson.errors.InvalidDocument:无法对对象进行编码:Decimal('25.96999999999998863131622783839702606201171875'),类型:<class 'decimal. Decimal'>
我必须存储浮点值吗?
我的问题的第二部分,如果我使用带引号的JSON,那么数字存储为字符串?JSON似乎缺乏标准,我看到的许多JSON都将所有值都放在引号中,甚至是数字。我该怎么办?
在我的实际应用程序中,我正在将CSV解析为字符串,但后来我注意到,即使是数字也被存储为字符串而不是数字,这就是为什么我写了上面的测试并问了这个问题。

0md85ypi

0md85ypi1#

对于存储为字符串的日期,请注意,strftime作为其名称返回一个字符串。
pymongo库包括日期时间的自动格式化,并将其直接存储为Mongo中的正确格式。
这同样适用于float(不是decimal)和int,因为在Python中类型是动态分配的,所以不需要强制转换。
我建议你尽可能多地使用float,如果你真的需要使用Decimal,那么你需要将它转换为Decimal128。此主题已经相关,请参阅:Pymongo: Cannot encode object of type decimal.Decimal?
如果你还有什么问题,请告诉我,我很乐意帮助你

crcmnpdw

crcmnpdw2#

这仍然是一个代码片段,但显示了如何使用十进制128。注意:在传递给Decimal128之前,必须用str()函数 Package 它。

from bson.decimal128 import Decimal128

    row_dict = {}
    row_dict['key'] = 'my string (default)'
    row_dict['myInteger'] = int(21)
    row_dict['myInteger2'] = 21
    row_dict['myInteger3'] = my_int_a
    row_dict['myInteger4'] = my_int_b
    row_dict['myCurrencyDecimal'] = Decimal128(str(25.97))
    row_dict['myCurrencyDouble'] = 25.97
    row_dict['myDateInsertedFmt'] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.000Z")
    row_dict['myDateInsertedNow'] = datetime.datetime.now()

    db_collection_test_datatypes.insert_one(row_dict)

在MongoDB中创建:

{
    "_id": ObjectId("65305679b5fb74135f65c921"),
    "key": "my string (default)",
    "myInteger": NumberInt("21"),
    "myInteger2": NumberInt("21"),
    "myInteger3": "21",
    "myInteger4": NumberInt("21"),
    "myCurrencyDecimal": NumberDecimal("25.97"),
    "myCurrencyDouble": 25.97,
    "myDateInsertedFmt": "2023-10-18T17:04:41.000Z",
    "myDateInsertedNow": ISODate("2023-10-18T17:04:41.798Z")
}

相关问题