| a | b | |
|---|
| 0 | + | def update_fields(self, record_id, fields): |
|---|
| 0 | + | """Safely update a number of fields. 'fields' being a |
|---|
| 0 | + | dictionary with path_tuple: value for only the fields we want |
|---|
| 0 | + | to change the value of, where path_tuple is a tuple of |
|---|
| 0 | + | fieldnames indicating the path to the possibly nested field |
|---|
| 0 | + | we're interested in. |
|---|
| 0 | + | """ |
|---|
| 0 | + | while True: |
|---|
| 0 | + | record = self.db[record_id] |
|---|
| 0 | + | modified = False |
|---|
| 0 | + | for path, value in fields.items(): |
|---|
| 0 | + | if not isinstance(path, tuple): |
|---|
| 0 | + | path = (path,) |
|---|
| 0 | + | parent = record |
|---|
| 0 | + | for field in path[:-1]: |
|---|
| 0 | + | parent = parent.setdefault(field, {}) |
|---|
| 0 | + | if parent.get(path[-1]) == value: |
|---|
| 0 | + | continue |
|---|
| 0 | + | modified = True |
|---|
| 0 | + | parent[path[-1]] = value |
|---|
| 0 | + | if modified: |
|---|
| 0 | + | try: |
|---|
| 0 | + | self.db[record.id] = record |
|---|
| 0 | + | except ResourceConflict: |
|---|
| 0 | + | logger.debug( |
|---|
| 0 | + | "Update of record with id %s in database %s failed." % ( |
|---|
| 0 | + | record_id, self.db.name)) |
|---|
| 0 | + | continue |
|---|
| 0 | + | break |
|---|
| ... | |
|---|