【问题标题】:Building a multiple nested dictionary using python使用python构建多嵌套字典
【发布时间】:2021-08-13 13:40:11
【问题描述】:

我正在努力构建一个多嵌套字典,我将使用它来添加到我在 mongodb 中的集合中。我质疑这种方法和我对解决方案的尝试。

问题来了: 我构建了一个函数,用于识别本地集合数据和我从黄金来源获得的更新之间的增量。

该函数生成所有 delta 的字典。字典包含标签作为键,新的增量更新作为值。

然后我将增量字典和当前数据字典传递给另一个函数,该函数负责执行以下操作:

  1. 使用 delta.key() 识别旧值和新值
  2. 构建一个新字典,其中应包含嵌套字典的完整路径,其中仅包含两个值:newValue 和 oldValue。

我正在努力解决的是,当我执行四次循环时,它似乎只是覆盖了之前的记录。数据应该被附加。如果路径存在,则更新时应该只添加到增量中。除非该值已经存在,否则我可以理解更新。 例如:

  1. 同一日期 -> 不同标签:应该附加新标签,它是旧值和新值。
  2. 同一日期->同一标签:应该更新现有标签的

我尝试以这种方式执行此操作的原因是为了避免多次调用和更新集合。最好坚持一次更新。

但我的担忧如下:

  1. 这是使用嵌套字典和 MongoDB 时的最佳方法吗?
  2. 当我使用“pymongo”更新 mongodb 时会出现什么问题。我担心它会覆盖更新的现有记录。我希望记录不会被覆盖。
  3. 有没有更有意义的不同方法?

这是我的第一次尝试1:

def update_record(_collection, _key, _data, _delta):
    today = date.today()
    today_formatted = today.strftime("%Y-%m-%d")
    _query_criteria = {_key: _data[_key]}
    _update_values = {}
    _append_delta = {}

    x = 0
    for delta_key in _delta.keys():
        _update_values = {delta_key: _delta[delta_key]}
            _append_delta["delta"]["byType"][delta_key][today_formatted] = {"oldValue": _data[delta_key],
                                                                            "newValue": _delta[delta_key]}
            _append_delta["delta"]["byDate"][today_formatted][delta_key] = {"oldValue": _data[delta_key],
                                                                            "newValue": _delta[delta_key]}

尝试 2:

def update_record(_collection, _key, _data, _delta):
    today = date.today()
    today_formatted = today.strftime("%Y-%m-%d")
    _query_criteria = {_key: _data[_key]}
    _update_values = {}
    _append_delta = {}

    x = 0
    for delta_key in _delta.keys():
        _update_values = {delta_key: _delta[delta_key]}
        x_dict = {}
        y_dict = {}

        if x == 0:
            _append_delta["delta"]["byType"] = {delta_key: {today_formatted: {}}}
            _append_delta["delta"]["byDate"][today_formatted] = {delta_key: {}}
            x += 1
            _append_delta["delta"]["byType"][delta_key][today_formatted] = {"oldValue": _data[delta_key],
                                                                            "newValue": _delta[delta_key]}
            _append_delta["delta"]["byDate"][today_formatted][delta_key] = {"oldValue": _data[delta_key],
                                                                            "newValue": _delta[delta_key]}

        else:
            _append_delta.update(
                {"delta":
                    {"byType": {
                        delta_key: {today_formatted: {"oldValue": _data[delta_key], "newValue": _delta[delta_key]}}},
                        "byDate": {
                            today_formatted: {delta_key: {"oldValue": _data[delta_key], "newValue": _delta[delta_key]}}}
                    }
                }
            )

我希望集合在 MongoDB 中的外观示例:

[{name: "Apple",
 ticker: "appl",
 description: "Apple Computers",
 currency: "usd",
 delta: {
     byTag: {
         name: {
             "2021-06-01": {
                 oldValue: "appl",
                 newValue: "Apple"
             }
         },
         description: {
             "2021-06-06": {
                 oldValue: "Apple",
                 newValue: "Apple Computers"
             }
         }
     },
     byDate: {
         "2021-06-01": {
             name: {
                 oldValue: "appl",
                 newValue: "Apple"
             }
         },
        "2021-06-06": {
             description: {
                 oldValue: "Apple",
                 newValue: "Apple Computers"
             }
         }

     }
 }
 }]

【问题讨论】:

    标签: python mongodb dictionary nested


    【解决方案1】:

    您在这里有很多问题。如果你把它们分解成小问题,你可能会得到更好的回应。

    在处理数据更改方面,您可能需要查看dictdiffer。就像 python 中的很多东西一样,通常有一个很好的库来实现你想要做的事情。它不会为您提供您正在寻找的格式,但会为您提供社区已确定是此类问题的最佳实践的格式。您还可以获得额外的好东西,例如能够使用 delta 修补旧记录。

    另外,对于嵌套字典,我认为基于对象结构创建它们比依赖于从键构建更容易。在我看来,它更冗长但更清晰。下面的代码是一个使用类的示例,让您了解这个概念:

    from pymongo import MongoClient
    from datetime import date
    from bson.json_util import dumps
    
    db = MongoClient()['mydatabase']
    
    
    class UpdateRecord:
        def __init__(self, name, ticker, description, currency, delta):
            self.name = name
            self.ticker = ticker
            self.description = description
            self.currency = currency
            self.date = date.today().strftime("%Y-%m-%d")
            self.delta = delta
            # Need to code to work out the deltas
    
        def by_tags(self):
            tags = dict()
            for tag in ['name', 'description']:
                tags.update({
                    tag: {
                        self.date: {
                            'oldValue': "appl",
                            'newValue': "Apple"
                        }
                    }
                })
            return tags
    
        def by_date(self):
            dates = dict()
            for dt in ['2021-06-01', '2021-06-06']:
                dates.update({
                    dt: {
                        self.date: {
                            'oldValue': "appl",
                            'newValue': "Apple"
                        }
                    }
                })
            return dates
    
        def to_dict(self):
            return {
                'name': self.name,
                'ticker': self.ticker,
                'description': self.description,
                'currency': self.currency,
                'delta': {
                    'byTag': self.by_tags(),
                    'byDate': self.by_date()
                }
            }
    
        def update(self, _id):
            db.mycollection.update_one({'_id': _id}, {'$push': {'Updates': self.to_dict()}})
    
    
    delta = {
        'oldValue': "appl",
        'newValue': "Apple"
    }
    #
    # Test it out
    #
    dummy_record = {'a': 1}
    db.mycollection.insert_one(dummy_record)
    record = db.mycollection.find_one()
    
    update_record = UpdateRecord(name='Apple', ticker='appl', description='Apple Computer', currency='usd', delta=delta)
    update_record.update(record.get('_id'))
    
    print(dumps(db.mycollection.find_one({}, {'_id': 0}), indent=4))
    

    打印:

    {
        "a": 1,
        "Updates": [
            {
                "name": "Apple",
                "ticker": "appl",
                "description": "Apple Computer",
                "currency": "usd",
                "delta": {
                    "byTag": {
                        "name": {
                            "2021-08-14": {
                                "oldValue": "appl",
                                "newValue": "Apple"
                            }
                        },
                        "description": {
                            "2021-08-14": {
                                "oldValue": "appl",
                                "newValue": "Apple"
                            }
                        }
                    },
                    "byDate": {
                        "2021-06-01": {
                            "2021-08-14": {
                                "oldValue": "appl",
                                "newValue": "Apple"
                            }
                        },
                        "2021-06-06": {
                            "2021-08-14": {
                                "oldValue": "appl",
                                "newValue": "Apple"
                            }
                        }
                    }
                }
            }
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-26
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 2017-08-08
      • 2023-01-18
      • 2022-01-25
      • 1970-01-01
      • 2021-08-21
      相关资源
      最近更新 更多