1
votes

Modifications enregistrées dans un journal d'audit

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 >


0 commentaires

3 Réponses :


2
votes

Et quelque chose comme ça? auditdiff accepte ici deux dictionnaires et génère 4 tuples décrivant les changements:

  • la première valeur est la clé affectée
  • la deuxième valeur est un verbe added/removed/changed
  • la troisième valeur est l'ancienne, le cas échéant
  • la quatrième valeur est la nouvelle valeur, le cas échéant

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)


0 commentaires

0
votes

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')]


0 commentaires

0
votes

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)


1 commentaires

Cela ne semble pas gérer correctement les clés ajoutées ou supprimées.