J'écris une petite application et je souhaite conserver un journal d'audit lisible par l'homme de toutes les modifications apportées à la base de données (évitant ainsi intentionnellement les outils qui consignent les modifications telles qu'elles sont écrites dans la base de données)
Le code ci-dessous fonctionne mais ce n'est pas le cas du tout élégant. Pouvez-vous trouver une manière plus élégante d'implémenter cela?
<class 'dict'>: {'note OLD': 'this is a note', 'note NEW': 'this is a changed note'}
Voici des exemples de variables capturées par le débogueur:
set1: ( anciennes valeurs)
<class 'dict'>: {'note': 'this is a changed note'}
set2: (nouvelles valeurs)
<class 'set'>: {('date', '2019-04-25'), ('note', 'this is a note'), ('student_id', None), ('charge', False), ('key', ''), ('status', 'ATTEND'), ('booking_id', '')}
diffset: (différence)
<class 'dict'>: {'date': '2019-04-25', 'student_id': None, 'booking_id': '', 'key': '', 'status': 'ATTEND', 'note': 'this is a changed note', 'charge': False}
m: (anciennes et nouvelles valeurs modifiées)
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)
Cordialement
James
p >
3 Réponses :
Et quelque chose comme ça? auditdiff accepte ici deux dictionnaires et génère 4 tuples décrivant les changements:
added/removed/changed Les modifications sont toujours émises dans l'ordre des clés lexicographiques.
('greeting', 'removed', 'hello', None)
('hello', 'added', None, 'world')
('note', 'changed', 'this is a changed note', 'this is a note')
sorties
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)
Solution un peu fantaisiste:
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')]
Voici une solution basée sur la vôtre. Cela suppose que les deux dictionnaires ont les mêmes clés.
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)
Cela ne semble pas gérer correctement les clés ajoutées ou supprimées.