changeset d27b905106dd in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=d27b905106dd
description:
Add validate option to trytond-admin
It validates a percentage of the listed models or all and report the
errors.
issue9782
review312751002
diffstat:
CHANGELOG | 1 +
trytond/admin.py | 39 +++++++++++++++++++++++++++++++++++++++
trytond/commandline.py | 5 +++++
3 files changed, 45 insertions(+), 0 deletions(-)
diffs (76 lines):
diff -r 32cd371b3e9c -r d27b905106dd CHANGELOG
--- a/CHANGELOG Wed Jan 20 00:52:07 2021 +0100
+++ b/CHANGELOG Mon Jan 25 22:56:02 2021 +0100
@@ -1,3 +1,4 @@
+* Add validate option to trytond-admin
* Refresh pool of other processes
* Add clear_all method to Cache
* Support Genshi element directives in HTML editor
diff -r 32cd371b3e9c -r d27b905106dd trytond/admin.py
--- a/trytond/admin.py Wed Jan 20 00:52:07 2021 +0100
+++ b/trytond/admin.py Mon Jan 25 22:56:02 2021 +0100
@@ -3,6 +3,7 @@
import sys
import os
import logging
+import random
from getpass import getpass
from sql import Table, Literal
@@ -119,3 +120,41 @@
if options.hostname is not None:
configuration.hostname = options.hostname or None
configuration.save()
+ with Transaction().start(db_name, 0, readonly=True):
+ if options.validate is not None:
+ validate(options.validate, options.validate_percentage)
+
+
+def validate(models, percentage=100):
+ from trytond.model import ModelStorage, ModelSingleton
+ from trytond.model.exceptions import ValidationError
+ logger = logging.getLogger('validate')
+ pool = Pool()
+ if not models:
+ models = sorted([n for n, _ in pool.iterobject()])
+ ratio = min(100, percentage) / 100
+ in_max = Transaction().database.IN_MAX
+ for name in models:
+ logger.info("validate: %s", name)
+ Model = pool.get(name)
+ if not issubclass(Model, ModelStorage):
+ continue
+ offset = 0
+ limit = in_max
+ while True:
+ records = Model.search(
+ [], order=[('id', 'ASC')], offset=offset, limit=limit)
+ if not records:
+ break
+ records = Model.browse(
+ random.sample(records, int(len(records) * ratio)))
+ for record in records:
+ try:
+ Model._validate([record])
+ except ValidationError as exception:
+ logger.error("%s: KO '%s'", record, exception)
+ else:
+ logger.info("%s: OK", record)
+ if issubclass(Model, ModelSingleton):
+ break
+ offset += limit
diff -r 32cd371b3e9c -r d27b905106dd trytond/commandline.py
--- a/trytond/commandline.py Wed Jan 20 00:52:07 2021 +0100
+++ b/trytond/commandline.py Mon Jan 25 22:56:02 2021 +0100
@@ -90,6 +90,11 @@
default=[], metavar='CODE', help="Load language translations")
parser.add_argument("--hostname", dest="hostname", default=None,
help="Limit database listing to the hostname")
+ parser.add_argument("--validate", dest="validate", nargs='*',
+ metavar='MODEL', help="validate records of models")
+ parser.add_argument("--validate-percentage", dest="validate_percentage",
+ type=float, default=100, metavar="PERCENTAGE",
+ help="percentage of records to validate (default: 100)")
parser.epilog = ('The first time a database is initialized '
'or when the password is set, the admin password is read '