nanterre: add an integrity_check command

It controls some invariants on the RSU data:
- people have an address,
- children have at most two adresses,
- children have at most two parents,
- adults are married to no more than one adult.
This commit is contained in:
Benjamin Dauvergne 2017-04-04 14:25:11 +02:00
parent cb07c0a6f6
commit cae5fe20ee
4 changed files with 75 additions and 1 deletions

View File

View File

@ -0,0 +1,26 @@
# zoo - versatile objects management
#
# Copyright (C) 2016 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.core.management.base import BaseCommand
from zoo.zoo_nanterre.utils import integrity_check
class Command(BaseCommand):
def handle(self, *args, **options):
for error in integrity_check():
print '!!!', error

View File

@ -5,6 +5,7 @@ import datetime
import isodate
import operator
import copy
import collections
from django.conf import settings
from django.contrib.postgres.search import TrigramDistance
@ -13,7 +14,7 @@ from django.db.models import Q, F, Value
from django.db.models.functions import Least, Greatest, Coalesce, Concat
from zoo.zoo_meta.models import EntitySchema
from zoo.zoo_data.models import Entity
from zoo.zoo_data.models import Entity, Relation
from zoo.zoo_data.search import JSONTextRef, Normalize
today = datetime.date.today
@ -435,3 +436,50 @@ class PersonSearch(object):
def __iter__(self):
return self.decorate_iter(self.queryset())
def integrity_check():
count_union_rels = collections.Counter()
count_parent_rels = collections.Counter()
count_habite_rels = collections.Counter()
rels = Relation.objects.select_related()
for rel in rels.filter(schema__slug=HABITE_REL):
count_habite_rels[rel.left] += 1
for rel in rels.filter(schema__slug=UNION_REL):
key = tuple(sorted([rel.left, rel.right], key=lambda x: x.id))
count_union_rels[key] += 1
count_union_rels[rel.left] += 1
count_union_rels[rel.right] += 1
for rel in rels.filter(schema__slug=RESPONSABILITE_LEGALE_REL):
count_parent_rels[rel.right] += 1
for key, value in count_union_rels.iteritems():
if value > 1:
if isinstance(key, tuple):
yield ("le couple %s / %s est en union plusieurs fois: %s"
% (key[0], key[1], value))
else:
yield ("l'individu %s est en union avec plus d'une personne: %s"
% (key, value))
for key, value in count_parent_rels.iteritems():
if value > 2:
yield ("l'enfant %s a plus de deux parents: %s"
% (key, value))
for key, value in count_habite_rels.iteritems():
if key.content['statut_legal'] == 'majeur' and value < 1:
yield ("l'adulte %s n'a pas d'adresse" % key)
if key.content['statut_legal'] == 'majeur' and value > 1:
yield ("l'adulte %s a plus d'une adresse: %s" % (key, value))
if key.content['statut_legal'] == 'mineur' and value > 2:
yield ("l'enfant %s a plus de deux adresses: %s" % (key, value))
if key.content['statut_legal'] == 'mineur' and value > 2:
yield ("l'enfant %s n'a pas d'adresse" % key)