将更改记录到审核日志中

时间:2019-04-23 09:21:57

标签: python flask

我正在编写一个小应用程序,并且希望保留人类可读的审计记录,以记录对数据库的任何更改(因此,有意避免使用记录更改写入数据库的工具)

下面的代码可以工作,但是一点也不优雅。您能用一种更优雅的方法来实现这一点吗?

def auditdiff(set1, set2):
    new = set(set1.items())
    old = set(session[set2].items())
    diffset = dict(old ^ new) # holds what has changed
    m = {}
    for d in diffset:
        for pair in old:
            if pair[0] == d:
                m[d + " OLD"] =  pair[1]

        for pair in new:
            if pair[0] == d:
                m[d + " NEW"] = pair[1]
    return(m)

以下是调试器捕获的变量示例:

set1 :(旧值)

<class 'dict'>: {'date': '2019-04-25', 'student_id': None, 'booking_id': '', 'key': '', 'status': 'ATTEND', 'note': 'this is a changed note', 'charge': False}

set2 :(新值)

<class 'set'>: {('date', '2019-04-25'), ('note', 'this is a note'), ('student_id', None), ('charge', False), ('key', ''), ('status', 'ATTEND'), ('booking_id', '')}

diffset :(差异)

<class 'dict'>: {'note': 'this is a changed note'}

m :(新旧更改的值)

<class 'dict'>: {'note OLD': 'this is a note', 'note NEW': 'this is a changed note'}

亲切的问候

詹姆斯

3 个答案:

答案 0 :(得分:2)

这样的事情怎么样? auditdiff在这里接受两个字典并生成描述更改的4元组:

  • 第一个值是受影响的键
  • 第二个值是动词added / removed / changed
  • 第三个值是旧值,如果有的话
  • 第四个值是新值(如果有)

更改始终按字典的键顺序发出。

def auditdiff(d1, d2):
    for key in sorted(set(d1) | set(d2)):
        if key in d1 and key not in d2:
            yield (key, "removed", d1[key], None)
        elif key in d2 and key not in d1:
            yield (key, "added", None, d2[key])
        elif d1[key] != d2[key]:
            yield (key, "changed", d1[key], d2[key])


d1 = {
    "date": "2019-04-25",
    "student_id": None,
    "booking_id": "",
    "key": "",
    "status": "ATTEND",
    "note": "this is a changed note",
    "charge": False,
    "greeting": "hello",  # this was added c.f. the original demo data
}
d2 = {
    "charge": False,
    "note": "this is a note",
    "key": "",
    "date": "2019-04-25",
    "student_id": None,
    "status": "ATTEND",
    "booking_id": "",
    "hello": "world",  # this was added c.f. the original demo data
}


for difference in auditdiff(d1, d2):
    print(difference)

输出

('greeting', 'removed', 'hello', None)
('hello', 'added', None, 'world')
('note', 'changed', 'this is a changed note', 'this is a note')

答案 1 :(得分:0)

一些异想天开的解决方案:

d1 = {
    "date": "2019-04-25",
    "student_id": None,
    "booking_id": "",
    "key": "",
    "status": "ATTEND",
    "note": "this is a changed note",
    "charge": False,
    "greeting": "hello",  # this was added c.f. the original demo data
}
d2 = {
    "charge": False,
    "note": "this is a note",
    "key": "",
    "date": "2019-04-25",
    "student_id": None,
    "status": "ATTEND",
    "booking_id": "",
    "hello": "world",  # this was added c.f. the original demo data
}

class LabeledTuple(tuple):
    def __new__(cls, t, label):
        result = super().__new__(cls, t)
        result.label = label
        return result

    def __repr__(self):
        return self.label + super().__repr__()


def labeled_set(d, name):
    return {LabeledTuple(t, name) for t in d.items()}


print(sorted(labeled_set(d1, "OLD") ^ labeled_set(d2, "NEW")))
# [OLD('greeting', 'hello'), NEW('hello', 'world'), OLD('note', 'this is a changed note'), NEW('note', 'this is a note')]

答案 2 :(得分:0)

这是基于您的解决方案。假定两个词典具有相同的键。

d1 = {
    "date": "2019-04-25",
    "student_id": None,
    "booking_id": "",
    "key": "",
    "status": "ATTEND",
    "note": "this is a changed note",
    "charge": False,
}
d2 = {
    "charge": False,
    "note": "this is a note",
    "key": "",
    "date": "2019-04-25",
    "student_id": None,
    "status": "ATTEND",
    "booking_id": "",
}

diffset = dict(set(d1.items()) ^ set(d2.items()))  # holds what has changed

m = {}
for key in diffset:
    m[key + " OLD"] = d1[key]
    m[key + " NEW"] = d2[key]

print(m)