TDDA’s Constraints API

tdda.constraints

tdda.constraints.discover_db_table(dbtype, db, tablename, inc_rex=False, seed=None)

Automatically discover potentially useful constraints that characterize the database table provided.

Input:

dbtype:
Type of database.
db:
a database object
tablename:
a table name

Possible return values:

This function goes through each column in the table and, where appropriate, generates constraints that describe (and are satisified by) this dataframe.

Assuming it generates at least one constraint for at least one field it returns a tdda.constraints.base.DatasetConstraints object.

This includes a ‘fields’ attribute, keyed on the column name.

The returned DatasetConstraints object includes a to_json() method, which converts the constraints into JSON for saving as a tdda constraints file. By convention, such JSON files use a ‘.tdda’ extension.

The JSON constraints file can be used to check whether other datasets also satisfy the constraints.

The kinds of constraints (potentially) generated for each field (column) are:

type:
the (coarse, TDDA) type of the field. One of ‘bool’, ‘int’, ‘real’, ‘string’ or ‘date’.
min:
for non-string fields, the minimum value in the column. Not generated for all-null columns.
max:
for non-string fields, the maximum value in the column. Not generated for all-null columns.
min_length:
For string fields, the length of the shortest string(s) in the field.
max_length:
For string fields, the length of the longest string(s) in the field.
sign:

If all the values in a numeric field have consistent sign, a sign constraint will be written with a value chosen from:

  • positive — For all values v in field: v > 0
  • non-negative — For all values v in field: v >= 0
  • zero — For all values v in field: v == 0
  • non-positive — For all values v in field: v <= 0
  • negative — For all values v in field: v < 0
  • null — For all values v in field: v is null
max_nulls:

The maximum number of nulls allowed in the field.

  • If the field has no nulls, a constraint will be written with max_nulls set to zero.
  • If the field has a single null, a constraint will be written with max_nulls set to one.
  • If the field has more than 1 null, no constraint will be generated.
no_duplicates:
For string fields (only, for now), if every non-null value in the field is different, this constraint will be generated (with value True); otherwise no constraint will be generated. So this constraint indicates that all the non-null values in a string field are distinct (unique).
allowed_values:
For string fields only, if there are MAX_CATEGORIES or fewer distinct string values in the dataframe, an AllowedValues constraint listing them will be generated. MAX_CATEGORIES is currently “hard-wired” to 20.

Regular Expression constraints are not (currently) generated for fields in database tables.

Example usage:

import pgdb
from tdda.constraints import discover_db_table

dbspec = 'localhost:databasename:username:password'
tablename = 'schemaname.tablename'
db = pgdb.connect(dbspec)
constraints = discover_db_table('postgres', db, tablename)

with open('myconstraints.tdda', 'w') as f:
    f.write(constraints.to_json())
tdda.constraints.verify_db_table(dbtype, db, tablename, constraints_path, epsilon=None, type_checking='strict', testing=False, report='all', **kwargs)

Verify that (i.e. check whether) the database table provided satisfies the constraints in the JSON .tdda file provided.

Mandatory Inputs:

dbtype:
Type of database.
db:
A database object
tablename:
A database table name, to be checked.
constraints_path:
The path to a JSON .tdda file (possibly generated by the discover_constraints function, below) containing constraints to be checked.

Optional Inputs:

epsilon:

When checking minimum and maximum values for numeric fields, this provides a tolerance. The tolerance is a proportion of the constraint value by which the constraint can be exceeded without causing a constraint violation to be issued.

For example, with epsilon set to 0.01 (i.e. 1%), values can be up to 1% larger than a max constraint without generating constraint failure, and minimum values can be up to 1% smaller that the minimum constraint value without generating a constraint failure. (These are modified, as appropriate, for negative values.)

If not specified, an epsilon of 0 is used, so there is no tolerance.

NOTE: A consequence of the fact that these are proportionate is that min/max values of zero do not have any tolerance, i.e. the wrong sign always generates a failure.

type_checking:

strict or sloppy. For databases (unlike Pandas DataFrames), this defaults to ‘strict’.

If this is set to sloppy, a database “real” column c will only be allowed to satisfy a an “int” type constraint.

report:

all or fields. This controls the behaviour of the __str__() method on the resulting DatabaseVerification object (but not its content).

The default is all, which means that all fields are shown, together with the verification status of each constraint for that field.

If report is set to fields, only fields for which at least one constraint failed are shown.

testing:
Boolean flag. Should only be set to True when being run as part of an automated test. It suppresses type-compatibility warnings.

Returns:

DatabaseVerification object.

This object has attributes:

  • passed — Number of passing constriants
  • failures — Number of failing constraints

Example usage:

import pgdb
from tdda.constraints import verify_db_table

dbspec = 'localhost:databasename:username:password'
tablename = 'schemaname.tablename'
db = pgdb.connect(dbspec)
v = verify_db_table('postgres' db, tablename, 'myconstraints.tdda')

print('Constraints passing:', v.passes)
print('Constraints failing: %d\n' % v.failures)
print(str(v))
tdda.constraints.detect_db_table(dbtype, db, tablename, constraints_path, epsilon=None, type_checking='strict', testing=False, **kwargs)

For detection of failures from verification of constraints, but not yet implemented for database tables.

TDDA constraint discovery and verification is provided for a number of DB-API (PEP-0249) compliant databases, and also for a number of other (NoSQL) databases.

The top-level functions are:

tdda.constraints.discover_db_table():
Discover constraints from a single database table.
tdda.constraints.verify_db_table():
Verify (check) a single database table, against a set of previously discovered constraints.
tdda.constraints.detect_db_table():
For detection of failing records in a single database table, but not yet implemented for databases.
class tdda.constraints.db.constraints.DatabaseConstraintCalculator(tablename, testing=False)
calc_all_non_nulls_boolean(colname)

Checks whether all the non-null values in a column are boolean. Returns True of they are, and False otherwise.

This is only required for implementations where a dataset column may contain values of mixed type.

calc_max(colname)

Calculates the maximum (non-null) value in the named column.

calc_max_length(colname)

Calculates the length of the longest string(s) in the named column.

calc_min(colname)

Calculates the minimum (non-null) value in the named column.

calc_min_length(colname)

Calculates the length of the shortest string(s) in the named column.

calc_non_integer_values_count(colname)

Calculates the number of unique non-integer values in a column

This is only required for implementations where a dataset column may contain values of mixed type.

calc_non_null_count(colname)

Calculates the number of nulls in a column

calc_null_count(colname)

Calculates the number of nulls in a column

calc_nunique(colname)

Calculates the number of unique non-null values in a column

calc_rex_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies a given regular expression constraint (by matching at least one of the regular expressions given).

Returns a ‘truthy’ value (typically the set of the strings that do not match any of the regular expressions) on failure, and a ‘falsy’ value (typically False or None or an empty set) if there are no failures. Any contents of the returned value are used in the case where detect is set, by the corresponding extension method for recording detection results.

calc_tdda_type(colname)

Calculates the TDDA type of a column

calc_unique_values(colname, include_nulls=True)

Calculates the set of unique values (including or excluding nulls) in a column

column_exists(colname)

Returns whether this column exists in the dataset

find_rexes(colname, values=None, seed=None)

Generate a list of regular expressions that cover all of the patterns found in the (string) column.

get_column_names()

Returns a list containing the names of all the columns

get_nrecords()

Return total number of records

is_null(value)

Determine whether a value is null

to_datetime(value)

Convert a value to a datetime

types_compatible(x, y, colname=None)

Determine whether the types of two values are compatible

class tdda.constraints.db.constraints.DatabaseConstraintVerifier(dbtype, db, tablename, epsilon=None, type_checking='strict', testing=False)

A DatabaseConstraintVerifier object provides methods for verifying every type of constraint against a single database table.

class tdda.constraints.db.constraints.DatabaseVerification(*args, **kwargs)

A DatabaseVerification object is the variant of the tdda.constraints.base.Verification object used for verification of constraints on a database table.

class tdda.constraints.db.constraints.DatabaseConstraintDiscoverer(dbtype, db, tablename, inc_rex=False, seed=None)

A DatabaseConstraintDiscoverer object is used to discover constraints on a single database table.

Extension Framework

The tdda command-line utility provides built-in support for constraint discovery and verification for tabular data stored in CSV files, Pandas DataFrames saved in .feather files, and for a tables in a variety of different databases.

The utility can be extended to provide support for constraint discovery and verification for other kinds of data, via its Python extension framework.

The framework will automatically use any extension implementations that have been declared using the TDDA_EXTENSIONS environment variable. This should be set to a list of class names, for Python classes that extend the ExtensionBase base class.

The class names in the TDDA_EXTENSIONS environment variable should be colon-separated for Unix systems, or semicolon-separated for Microsoft Windows. To be usable, the classes must be accessible by Python (either by being installed in Pythons standard module directory, or by being included in the PYTHONPATH environment variable.

For example:

export TDDA_EXTENSIONS="mytdda.MySpecialExtension"
export PYTHONPATH="/my/python/sources:$PYTHONPATH"

With these in place, the tdda command will include constraint discovery and verification using the MySpecialExtension implementation class provided in the Python file /my/python/sources/mytdda.py.

An example of a simple extension is included with the set of standard examples. See Examples.

Extension Overview

An extension should provide:

  • an implementation (subclass) of ExtensionBase, to provide a command-line interface, extending the tdda command to support a particular type of input data.
  • an implementation (subclass) of BaseConstraintCalculator, to provide methods for computing individual constraint results.
  • an implementation (subclass) of BaseConstraintDetector, to provide methods for generating detection results.

A typical implementation looks like:

from tdda.constraints.flags import discover_parser, discover_flags
from tdda.constraints.flags import verify_parser, verify_flags
from tdda.constraints.flags import detect_parser, detect_flags
from tdda.constraints.extension import ExtensionBase
from tdda.constraints.base import DatasetConstraints, Detection
from tdda.constraints.baseconstraints import (BaseConstraintCalculator,
                                              BaseConstraintVerifier,
                                              BaseConstraintDetector,
                                              BaseConstraintDiscoverer)
from tdda.rexpy import rexpy

class MyExtension(ExtensionBase):
    def applicable(self):
        ...

    def help(self, stream=sys.stdout):
        print('...', file=stream)

    def spec(self):
        return '...'

    def discover(self):
        parser = discover_parser()
        parser.add_argument(...)
        params = {}
        flags = discover_flags(parser, self.argv[1:], params)
        data = ... get data source from flags ...
        discoverer = MyConstraintDiscoverer(data, **params)
        constraints = discoverer.discover()
        results = constraints.to_json()
        ... write constraints JSON to output file
        return results

    def verify(self):
        parser = verify_parser()
        parser.add_argument(...)
        params = {}
        flags = verify_flags(parser, self.argv[1:], params)
        data = ... get data source from flags ...
        verifier = MyConstraintVerifier(data, **params)
        constraints = DatasetConstraints(loadpath=...)
        results = verifier.verify(constraints)
        return results

    def detect(self):
        parser = detect_parser()
        parser.add_argument(...)
        params = {}
        flags = detect_flags(parser, self.argv[1:], params)
        data = ... get data source from flags ...
        detector = MyConstraintDetector(data, **params)
        constraints = DatasetConstraints(loadpath=...)
        results = detector.detect(constraints)
        return results

Extension API

class tdda.constraints.extension.BaseConstraintCalculator

The BaseConstraintCalculator class defines a default or dummy implementation of all of the methods that are required in order to implement a constraint discoverer or verifier via subclasses of the base BaseConstraintDiscoverer and BaseConstraintVerifier classes.

allowed_values_exclusions()

Get list of values to ignore when computing allowed values

calc_all_non_nulls_boolean(colname)

Checks whether all the non-null values in a column are boolean. Returns True of they are, and False otherwise.

This is only required for implementations where a dataset column may contain values of mixed type.

calc_max(colname)

Calculates the maximum (non-null) value in the named column.

calc_max_length(colname)

Calculates the length of the longest string(s) in the named column.

calc_min(colname)

Calculates the minimum (non-null) value in the named column.

calc_min_length(colname)

Calculates the length of the shortest string(s) in the named column.

calc_non_integer_values_count(colname)

Calculates the number of unique non-integer values in a column

This is only required for implementations where a dataset column may contain values of mixed type.

calc_non_null_count(colname)

Calculates the number of nulls in a column

calc_null_count(colname)

Calculates the number of nulls in a column

calc_nunique(colname)

Calculates the number of unique non-null values in a column

calc_rex_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies a given regular expression constraint (by matching at least one of the regular expressions given).

Returns a ‘truthy’ value (typically the set of the strings that do not match any of the regular expressions) on failure, and a ‘falsy’ value (typically False or None or an empty set) if there are no failures. Any contents of the returned value are used in the case where detect is set, by the corresponding extension method for recording detection results.

calc_tdda_type(colname)

Calculates the TDDA type of a column

calc_unique_values(colname, include_nulls=True)

Calculates the set of unique values (including or excluding nulls) in a column

column_exists(colname)

Returns whether this column exists in the dataset

find_rexes(colname, values=None)

Generate a list of regular expressions that cover all of the patterns found in the (string) column.

get_column_names()

Returns a list containing the names of all the columns

get_nrecords()

Return total number of records

is_null(value)

Determine whether a value is null

to_datetime(value)

Convert a value to a datetime

types_compatible(x, y, colname)

Determine whether the types of two values are compatible

class tdda.constraints.extension.BaseConstraintDetector

The BaseConstraintDetector class defines a default or dummy implementation of all of the methods that are required in order to implement constraint detection via the a subclass of the base BaseConstraintVerifier class.

detect_allowed_values_constraint(colname, value, violations)

Detect failures for an allowed_values constraint.

detect_max_constraint(colname, value, precision, epsilon)

Detect failures for a max constraint.

detect_max_length_constraint(colname, value)

Detect failures for a max_length constraint.

detect_max_nulls_constraint(colname, value)

Detect failures for a max_nulls constraint.

detect_min_constraint(colname, value, precision, epsilon)

Detect failures for a min constraint.

detect_min_length_constraint(colname, value)

Detect failures for a min_length constraint.

detect_no_duplicates_constraint(colname, value)

Detect failures for a no_duplicates constraint.

detect_rex_constraint(colname, value, violations)

Detect failures for a rex constraint.

detect_sign_constraint(colname, value)

Detect failures for a sign constraint.

detect_tdda_type_constraint(colname, value)

Detect failures for a type constraint.

write_detected_records(detect_outpath=None, detect_write_all=False, detect_per_constraint=False, detect_output_fields=None, detect_index=False, detect_in_place=False, rownumber_is_index=True, boolean_ints=False, **kwargs)

Write out a detection dataset.

Returns a :py:class:~tdda.constraints.base.Detection object (or None).

class tdda.constraints.extension.ExtensionBase(argv, verbose=False)

An extension must provide a class that is based on the ExtensionBase class, providing implementations for its applicable(), help(), discover() and verify() methods.

applicable()

The applicable() method should return True if the argv property contains command-line parameters that can be used by this implementation.

For example, if the extension can handle data stored in Excel .xlsx files, then its applicable() method should return True if any of its parameters are filenames that have a .xlsx suffix.

detect()

The detect() method should implement constraint detection.

It should read constraints from a .tdda file specified on the command line, and verify these constraints on the data specified, and produce detection output.

It should use the self.argv variable to get whatever other optional or mandatory flags or parameters are required to specify the data on which the constraints are to be verified, where the output detection data should be written, and detection-specific flags.

discover()

The discover() method should implement constraint discovery.

It should use the self.argv variable to get whatever other optional or mandatory flags or parameters are required to specify the data from which constraints are to be discovered, and the name of the file to which the constraints are to be written.

help(self, stream=sys.stdout)

The help() method should document itself by writing lines to the given output stream.

This is used by the tdda command’s help option.

spec()

The spec() method should return a short one-line string describing, briefly, how to specify the input source.

verify()

The verify() method should implement constraint verification.

It should read constraints from a .tdda file specified on the command line, and verify these constraints on the data specified.

It should use the self.argv variable to get whatever other optional or mandatory flags or parameters are required to specify the data on which the constraints are to be verified.

Constraints API

TDDA constraint discovery and verification, common underlying functionality.

class tdda.constraints.baseconstraints.BaseConstraintDiscoverer(inc_rex=False, seed=None, **kwargs)

The BaseConstraintDiscoverer class provides a generic framework for discovering constraints.

A concrete implementation of this class is constructed by creating a mix-in subclass which inherits both from BaseConstraintDiscover and from a specific implementation of BaseConstraintCalculator.

class tdda.constraints.baseconstraints.BaseConstraintVerifier(epsilon=None, type_checking=None, **kwargs)

The BaseConstraintVerifier class provides a generic framework for verifying constraints.

A concrete implementation of this class is constructed by creating a mix-in subclass which inherits both from BaseConstraintVerifier and from specific implementations of BaseConstraintCalculator and BaseConstraintDetector.

cache_values(colname)

Returns the dictionary for colname from the cache, first creating it if there isn’t one on entry.

detect(constraints, VerificationClass=<class 'tdda.constraints.base.Verification'>, outpath=None, write_all=False, per_constraint=False, output_fields=None, index=False, in_place=False, rownumber_is_index=True, boolean_ints=False, **kwargs)

Apply verifiers to a set of constraints, for detection.

Note that if there is a constraint for a field that does not exist, then it fails verification, but there are no records to detect against. Similarly if the field exists but the dataset has no records.

get_all_non_nulls_boolean(colname)

Looks up or caches the number of non-integer values in a real column, or calculates and caches it.

get_cached_value(value, colname, f)

Return cached value of colname, calculating it and caching it first, if it is not already there.

get_max(colname)

Looks up cached maximum of column, or calculates and caches it

get_max_length(colname)

Looks up cached maximum string length in column, or calculates and caches it

get_min(colname)

Looks up cached minimum of column, or calculates and caches it

get_min_length(colname)

Looks up cached minimum string length in column, or calculates and caches it

get_non_integer_values_count(colname)

Looks up or caches the number of non-integer values in a real column, or calculates and caches it.

get_non_null_count(colname)

Looks up or caches the number of non-null values in a column, or calculates and caches it

get_null_count(colname)

Looks up or caches the number of nulls in a column, or calculates and caches it

get_nunique(colname)

Looks up or caches the number of unique (distinct) values in a column, or calculates and caches it.

get_tdda_type(colname)

Looks up cached tdda type of a column, or calculates and caches it

get_unique_values(colname)

Looks up or caches the list of unique (distinct) values in a column, or calculates and caches it.

verifiers()

Returns a dictionary mapping constraint types to their callable (bound) verification methods.

verify(constraints, VerificationClass=<class 'tdda.constraints.base.Verification'>, **kwargs)

Apply verifiers to a set of constraints, for reporting

verify_allowed_values_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies the constraint on allowed (string) values provided.

verify_max_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies the maximum value constraint specified.

verify_max_length_constraint(colname, constraint, detect=False)

Verify whether a given (string) column satisfies the maximum length constraint specified.

verify_max_nulls_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies the supplied constraint that it should contain no nulls.

verify_min_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies the minimum value constraint specified.

verify_min_length_constraint(colname, constraint, detect=False)

Verify whether a given (string) column satisfies the minimum length constraint specified.

verify_no_duplicates_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies the constraint supplied, that it should contain no duplicate (non-null) values.

verify_rex_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies a given regular expression constraint (by matching at least one of the regular expressions given).

verify_sign_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies the supplied sign constraint.

verify_tdda_type_constraint(colname, constraint, detect=False)

Verify whether a given column satisfies the supplied type constraint.

Underlying API Classes

Classes for representing individual constraints.

class tdda.constraints.base.DatasetConstraints(per_field_constraints=None, loadpath=None)

Container for constraints pertaining to a dataset. Currently only supports per-field constraints.

initialize_from_dict(in_constraints)

Initializes this object from a dictionary in_constraints. Currently, the only key used from in_constraints is fields.

The value of in_constraints[‘fields’] is expected to be a dictionary, keyed on field name, whose values are the constraints for that field.

They constraints are keyed on the kind of constraint, and should contain either a single value (a scalar or a list), or a dictionary of keyword arguments for the constraint initializer.

load(path)

Builds a DatasetConstraints object from a json file

sort_fields(fields=None)

Sorts the field constraints within the object by field order, by default by alphabetical order.

If a list of field names is provided, then the fields will appear in that given order (with any additional fields appended at the end).

to_dict(tddafile=None)

Converts the constraints in this object to a dictionary.

to_json(tddafile=None)

Converts the constraints in this object to JSON. The resulting JSON is returned.

class tdda.constraints.base.FieldConstraints(name=None, constraints=None)

Container for constraints on a field.

to_dict_value(raw=False)

Returns a pair consisting of the name supplied, or the stored name, and an ordered dictionary keyed on constraint kind with the value specifying the constraint. For simple constraints, the value is a base type; for more complex constraints with several components, the value will itself be an (ordered) dictionary.

The ordering is all to make the JSON file get written in a sensible order, rather than being a jumbled mess.

class tdda.constraints.base.MultiFieldConstraints(names=None, constraints=None)

Container for constraints on a pairs (or higher numbers) of fields

to_dict_value()
Returns a pair consisting of
  • a comma-separated list of the field names
  • an ordered dictionary keyed on constraint kind with the value specifying the constraint.

For simple constraints, the value is a base type; for more complex Constraints with several components, the value will itself be an (ordered) dictionary.

The ordering is all to make the JSON file get written in a sensible order, rather than being a jumbled mess.

class tdda.constraints.base.Constraint(kind, value, **kwargs)

Base container for a single constraint. All specific constraint types (should) subclass this.

check_validity(name, value, *valids)

Check that the value of a constraint is allowed. If it isn’t, then the TDDA file is not valid.

class tdda.constraints.base.MinConstraint(value, precision=None, comment=None)

Constraint specifying the minimum allowed value in a field.

class tdda.constraints.base.MaxConstraint(value, precision=None, comment=None)

Constraint specifying the maximum allowed value in a field.

class tdda.constraints.base.SignConstraint(value, comment=None)

Constraint specifying allowed sign of values in a field. Used only for numeric fields (real, int, bool), and normally used in addition to Min and Max constraints.

Possible values are positive, non-negative, zero, non-positive, negative and null.

class tdda.constraints.base.TypeConstraint(value, comment=None)

Constraint specifying the allowed (TDDA) type of a field. This can be a single value, chosen from:

  • bool
  • int
  • real
  • string
  • date

or a list of such values, most commonly ['int', 'real'], sometimes used because of Pandas silent and automatic promotion of integer fields to floats if nulls are present.)

class tdda.constraints.base.MaxNullsConstraint(value, comment=None)

Constraint on the maximum number of nulls allowed in a field. Usually 0 or 1. (The constraint generator only generates 0 and 1, but the verifier will verify and number.)

class tdda.constraints.base.NoDuplicatesConstraint(value=True, comment=None)

Constraint specifying that non dupicate non-null values are allowed in a field.

Currently only generated for string fields, though could be used more broadly.

class tdda.constraints.base.AllowedValuesConstraint(value, comment=None)

Constraint restricting the allowed values in a field to an explicity list.

Currently only used for string fields.

When generating constraints, this code will only generate such a constraint if there are no more than MAX_CATEGORIES (= 20 at the time of writing, but check above in case this comment rusts) different values in the field.

class tdda.constraints.base.MinLengthConstraint(value)

Constraint restricting the minimum length of strings in a string field.

Generated instead of a MinConstraint by this generation code, but can be used in conjunction with a MinConstraint.

class tdda.constraints.base.MaxLengthConstraint(value, comment=None)

Constraint restricting the maximum length of strings in a string field.

Generated instead of a MaxConstraint by this generation code, but can be used in conjunction with a MinConstraint.

class tdda.constraints.base.LtConstraint(value)

Constraint specifying that the first field of a pair should be (strictly) less than the second, where both are non-null.

class tdda.constraints.base.LteConstraint(value)

Constraint specifying that the first field of a pair should be no greater than the second, where both are non-null.

class tdda.constraints.base.EqConstraint(value)

Constraint specifying that two fields should have identical values where they are both non-null.

class tdda.constraints.base.GtConstraint(value)

Constraint specifying that the first field of a pair should be (strictly) greater than the second, where both are non-null.

class tdda.constraints.base.GteConstraint(value)

Constraint specifying that the first field of a pair should be greater than or equal to the second, where both are non-null.

class tdda.constraints.base.RexConstraint(value, comment=None)

Constraint restricting a string field to match (at least) one of the regular expressions in a list given.

class tdda.constraints.base.Verification(constraints, report='all', ascii=False, detect=False, detect_outpath=None, detect_write_all=False, detect_per_constraint=False, detect_output_fields=None, detect_index=False, detect_in_place=False, **kwargs)

Container for the result of a constraint verification for a dataset in the context of a given set of constraints.