google-pso-data-validator 4.5.0__tar.gz → 5.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/PKG-INFO +18 -20
  2. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/README.md +17 -19
  3. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/__main__.py +16 -10
  4. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/cli_tools.py +33 -32
  5. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/config_manager.py +18 -8
  6. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/consts.py +1 -1
  7. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/data_validation.py +28 -14
  8. google_pso_data_validator-5.0.0/data_validation/gcs_helper.py +94 -0
  9. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/partition_builder.py +2 -2
  10. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/query_builder/query_builder.py +12 -5
  11. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/secret_manager.py +5 -0
  12. google_pso_data_validator-5.0.0/data_validation/state_manager.py +126 -0
  13. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/google_pso_data_validator.egg-info/PKG-INFO +18 -20
  14. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/google_pso_data_validator.egg-info/SOURCES.txt +1 -0
  15. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/setup.py +1 -1
  16. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_addon/operations.py +116 -7
  17. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_db2/registry.py +2 -1
  18. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_impala/api.py +2 -0
  19. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_teradata/datatypes.py +7 -0
  20. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_teradata/registry.py +34 -1
  21. google-pso-data-validator-4.5.0/data_validation/state_manager.py +0 -277
  22. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/LICENSE +0 -0
  23. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/__init__.py +0 -0
  24. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/app.py +0 -0
  25. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/client_info.py +0 -0
  26. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/clients.py +0 -0
  27. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/combiner.py +0 -0
  28. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/exceptions.py +0 -0
  29. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/jellyfish_distance.py +0 -0
  30. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/metadata.py +0 -0
  31. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/query_builder/__init__.py +0 -0
  32. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/query_builder/partition_row_builder.py +0 -0
  33. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/query_builder/random_row_builder.py +0 -0
  34. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/result_handlers/__init__.py +0 -0
  35. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/result_handlers/bigquery.py +0 -0
  36. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/result_handlers/text.py +0 -0
  37. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/schema_validation.py +0 -0
  38. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/data_validation/validation_builder.py +0 -0
  39. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/google_pso_data_validator.egg-info/dependency_links.txt +0 -0
  40. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/google_pso_data_validator.egg-info/entry_points.txt +0 -0
  41. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/google_pso_data_validator.egg-info/requires.txt +0 -0
  42. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/google_pso_data_validator.egg-info/top_level.txt +0 -0
  43. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/setup.cfg +0 -0
  44. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_addon/__init__.py +0 -0
  45. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_addon/api.py +0 -0
  46. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/__init__.py +0 -0
  47. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/api.py +0 -0
  48. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/client.py +0 -0
  49. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/compiler.py +0 -0
  50. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/datatypes.py +0 -0
  51. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/registry.py +0 -0
  52. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/tests/__init__.py +0 -0
  53. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/tests/conftest.py +0 -0
  54. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_cloud_spanner/to_pandas.py +0 -0
  55. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_db2/__init__.py +0 -0
  56. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_db2/api.py +0 -0
  57. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_db2/compiler.py +0 -0
  58. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_db2/datatypes.py +0 -0
  59. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_impala/__init__.py +0 -0
  60. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_mssql/__init__.py +0 -0
  61. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_mssql/api.py +0 -0
  62. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_mssql/datatypes.py +0 -0
  63. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_mysql/__init__.py +0 -0
  64. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_mysql/base_sql_compiler/__init__.py +0 -0
  65. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_mysql/base_sql_compiler/select_builder.py +0 -0
  66. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_mysql/compiler.py +0 -0
  67. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_oracle/__init__.py +0 -0
  68. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_oracle/api.py +0 -0
  69. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_oracle/compiler.py +0 -0
  70. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_oracle/datatypes.py +0 -0
  71. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_oracle/registry.py +0 -0
  72. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_postgres/__init__.py +0 -0
  73. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_postgres/client.py +0 -0
  74. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_postgres/datatypes.py +0 -0
  75. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_redshift/__init__.py +0 -0
  76. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_redshift/api.py +0 -0
  77. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_redshift/compiler.py +0 -0
  78. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_snowflake/__init__.py +0 -0
  79. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_snowflake/api.py +0 -0
  80. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_snowflake/datatypes.py +0 -0
  81. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_teradata/__init__.py +0 -0
  82. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_teradata/api.py +0 -0
  83. {google-pso-data-validator-4.5.0 → google_pso_data_validator-5.0.0}/third_party/ibis/ibis_teradata/compiler.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: google-pso-data-validator
3
- Version: 4.5.0
3
+ Version: 5.0.0
4
4
  Summary: A package to enable easy data validation
5
5
  Home-page: https://github.com/pypa/sampleproject
6
6
  Author: Dylan Hercher
@@ -172,7 +172,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate column
172
172
  If target filter is not provided, the source filter will run on source and target tables.
173
173
  See: *Filters* section
174
174
  [--config-file or -c CONFIG_FILE]
175
- YAML Config File Path to be used for storing validations and other features.
175
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
176
176
  See: *Running DVT with YAML Configuration Files* section
177
177
  [--config-file-json or -cj CONFIG_FILE_JSON]
178
178
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -242,7 +242,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate row
242
242
  If target filter is not provided, the source filter will run on source and target tables.
243
243
  See: *Filters* section
244
244
  [--config-file or -c CONFIG_FILE]
245
- YAML Config File Path to be used for storing validations and other features.
245
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
246
246
  See: *Running DVT with YAML Configuration Files* section
247
247
  [--config-file-json or -cj CONFIG_FILE_JSON]
248
248
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -322,7 +322,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate schema
322
322
  [--service-account or -sa PATH_TO_SA_KEY]
323
323
  Service account to use for BigQuery result handler output.
324
324
  [--config-file or -c CONFIG_FILE]
325
- YAML Config File Path to be used for storing validations and other features.
325
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
326
326
  See: *Running DVT with YAML Configuration Files* section
327
327
  [--config-file-json or -cj CONFIG_FILE_JSON]
328
328
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -369,7 +369,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate custom-query col
369
369
  [--max COLUMNS] Comma separated list of columns for max or * for all numeric
370
370
  [--avg COLUMNS] Comma separated list of columns for avg or * for all numeric
371
371
  [--std COLUMNS] Comma separated list of columns for stddev_samp or * for all numeric
372
- [--exclude-columns or -ec]
372
+ [--exclude-columns or -ec]
373
373
  Flag to indicate the list of columns provided should be excluded and not included.
374
374
  [--bq-result-handler or -bqrh PROJECT_ID.DATASET.TABLE]
375
375
  BigQuery destination for validation results. Defaults to stdout.
@@ -377,7 +377,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate custom-query col
377
377
  [--service-account or -sa PATH_TO_SA_KEY]
378
378
  Service account to use for BigQuery result handler output.
379
379
  [--config-file or -c CONFIG_FILE]
380
- YAML Config File Path to be used for storing validations and other features.
380
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
381
381
  See: *Running DVT with YAML Configuration Files* section
382
382
  [--config-file-json or -cj CONFIG_FILE_JSON]
383
383
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -439,7 +439,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate custom-query row
439
439
  [--service-account or -sa PATH_TO_SA_KEY]
440
440
  Service account to use for BigQuery result handler output.
441
441
  [--config-file or -c CONFIG_FILE]
442
- YAML Config File Path to be used for storing validations and other features.
442
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
443
443
  See: *Running DVT with YAML Configuration Files* section
444
444
  [--config-file-json or -cj CONFIG_FILE_JSON]
445
445
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -483,11 +483,10 @@ For example, this flag can be used as follows:
483
483
 
484
484
  Running DVT with YAML configuration files is the recommended approach if:
485
485
  * you want to customize the configuration for any given validation OR
486
- * you want to run DVT at scale (i.e. row validations across many partitions)
486
+ * you want to run DVT at scale (i.e. run multiple validations sequentially or in parallel)
487
487
 
488
- We recommend generating YAML configs with the `--config-file <file-name>` flag when running a validation command. The validation
489
- config file is saved to the GCS path specified by the `PSO_DV_CONFIG_HOME` env variable if that has been set;
490
- otherwise, it is saved to wherever the tool is run.
488
+ We recommend generating YAML configs with the `--config-file <file-name>` flag when running a validation command, which supports
489
+ GCS and local paths.
491
490
 
492
491
  You can use the `data-validation configs` command to run and view YAMLs.
493
492
 
@@ -500,7 +499,7 @@ data-validation (--verbose or -v) (--log-level or -ll) configs run
500
499
  [--dry-run or -dr] If this flag is present, prints the source and target SQL generated in lieu of running the validation.
501
500
  [--kube-completions or -kc]
502
501
  Flag to indicate usage in Kubernetes index completion mode.
503
- See *Scaling DVT to run 10's to 1000's of validations concurrently* section
502
+ See *Scaling DVT* section
504
503
  ```
505
504
 
506
505
  ```
@@ -518,19 +517,17 @@ View the complete YAML file for a Grouped Column validation on the
518
517
  [Examples](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/examples.md#sample-yaml-config-grouped-column-validation) page.
519
518
 
520
519
 
521
- #### Scaling DVT to run 10's to 1000's of validations concurrently
520
+ ### Scaling DVT
522
521
 
523
- As described above, you can run multiple validation configs sequentially with the `--config-dir` flag. To optimize the validation speed for large tables, you can run DVT concurrently using GKE Jobs ([Google Kubernetes Jobs](https://cloud.google.com/kubernetes-engine/docs/how-to/deploying-workloads-overview#batch_jobs)) or [Cloud Run Jobs](https://cloud.google.com/run/docs/create-jobs). If you are not familiar with Kubernetes or Cloud Run Jobs, see [Scaling DVT with Kubernetes](docs/internal/kubernetes_jobs.md) for a detailed overview.
522
+ You can scale DVT for large table validations by running the tool in a distributed manner. To optimize the validation speed for large tables, you can use GKE Jobs ([Google Kubernetes Jobs](https://cloud.google.com/kubernetes-engine/docs/how-to/deploying-workloads-overview#batch_jobs)) or [Cloud Run Jobs](https://cloud.google.com/run/docs/create-jobs). If you are not familiar with Kubernetes or Cloud Run Jobs, see [Scaling DVT with Distributed Jobs](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/internal/distributed_jobs.md) for a detailed overview.
524
523
 
525
- In order to validate partitions concurrently, both the `--kube-completions` and `--config-dir` flags are required. The `--kube-completions` flag specifies that the validation is being run in indexed completion mode in Kubernetes or as multiple independent tasks in Cloud Run. The `--config-dir` flag will specify the directory with the YAML files to be executed in parallel. If you used `generate-table-partitions` to generate the YAMLs, this would be the directory where the partition files numbered `0000.yaml` to `<partition_num - 1>.yaml` are stored i.e (`my_config_dir/source_schema.source_table/`)
526
524
 
527
- In order to run DVT in a container, you have to build a Docker image - [see instructions here](https://github.com/GoogleCloudPlatform/professional-services-data-validator/tree/develop/samples/docker#readme). You will also need to set the `PSO_DV_CONFIG_HOME` environment variable to point to a GCS prefix where the connection configuration files are stored. In Cloud Run you can use the option `--set-env-vars` or `--update-env-vars` to pass [the environment variable](https://cloud.google.com/run/docs/configuring/services/environment-variables#setting). We recommend that you use the `bq-result-handler` to save your validation results to BigQuery.
525
+ We recommend first generating table partitions with the `generate-table-partitions` command for your large tables. Then, use Cloud Run or GKE to distribute validating each chunk in parallel. See the [Cloud Run Jobs Quickstart sample](https://github.com/GoogleCloudPlatform/professional-services-data-validator/tree/develop/samples/cloud_run_jobs) to get started.
528
526
 
529
- The Cloud Run and Kubernetes pods must run in a network with access to the database servers. Every Cloud Run job is associated with a [service account](https://cloud.google.com/run/docs/securing/service-identity). You need to ensure that this service account has access to Google Cloud Storage (to read connection configuration and YAML files) and BigQuery (to publish results). If you are using Kubernetes, you will need to use a service account with the same privileges as mentioned for Cloud Run. In Kubernetes, you will need to set up [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) so the DVT container can impersonate the service account.
527
+ When running DVT in a distributed fashion, both the `--kube-completions` and `--config-dir` flags are required. The `--kube-completions` flag specifies that the validation is being run in indexed completion mode in Kubernetes or as multiple independent tasks in Cloud Run. If the `-kc` option is used and you are not running in indexed mode, you will receive a warning and the container will process all the validations sequentially. If the `-kc` option is used and a config directory is not provided (i.e. a `--config-file` is provided instead), a warning is issued.
530
528
 
531
- In Cloud Run, the [job](https://cloud.google.com/run/docs/create-jobs) must be run as multiple, independent tasks with the task count set to the number of partitions generated. In Kubernetes, set the number of completions to the number of partitions generated - see [Kubernetes Parallel Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/job/#parallel-jobs). The option `--kube-completions or -kc` tells DVT that many DVT containers are running in a Kubernetes cluster. Each DVT container only validates the specific partition YAML (based on the index assigned by Kubernetes control plane). If the `-kc` option is used and you are not running in indexed mode, you will receive a warning and the container will process all the validations sequentially. If the `-kc` option is used and a config directory is not provided (a `--config-file` is provided instead), a warning is issued.
529
+ The `--config-dir` flag will specify the directory with the YAML files to be executed in parallel. If you used `generate-table-partitions` to generate the YAMLs, this would be the directory where the partition files numbered `0000.yaml` to `<partition_num - 1>.yaml` are stored i.e (`gs://my_config_dir/source_schema.source_table/`). When creating your Cloud Run Job, set the number of tasks equal to the number of table partitions so the task index matches the YAML file to be validated. When executed, each Cloud Run task will validate a partition in parallel.
532
530
 
533
- By default, each partition validation is retried up to 3 times if there is an error. In Kubernetes and Cloud Run, you can set the parallelism to the number you want. Keep in mind that if you are validating 1000's of partitions in parallel, you may find that setting the parallelism too high (say 100) may result in timeouts and slow down the validation.
534
531
 
535
532
  ### Validation Reports
536
533
 
@@ -635,7 +632,8 @@ with calculated fields as shown in [this example](https://github.com/GoogleCloud
635
632
 
636
633
  Filters let you apply a WHERE statement to your validation query (ie. `SELECT *
637
634
  FROM table WHERE created_at > 30 days ago AND region_id = 71;`). The filter is
638
- written in the syntax of the given source.
635
+ written in the syntax of the given source and must reference columns in the
636
+ underlying table, not projected DVT expressions.
639
637
 
640
638
  Note that you are writing the query to execute, which does not have to match
641
639
  between source and target as long as the results can be expected to align. If
@@ -124,7 +124,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate column
124
124
  If target filter is not provided, the source filter will run on source and target tables.
125
125
  See: *Filters* section
126
126
  [--config-file or -c CONFIG_FILE]
127
- YAML Config File Path to be used for storing validations and other features.
127
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
128
128
  See: *Running DVT with YAML Configuration Files* section
129
129
  [--config-file-json or -cj CONFIG_FILE_JSON]
130
130
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -194,7 +194,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate row
194
194
  If target filter is not provided, the source filter will run on source and target tables.
195
195
  See: *Filters* section
196
196
  [--config-file or -c CONFIG_FILE]
197
- YAML Config File Path to be used for storing validations and other features.
197
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
198
198
  See: *Running DVT with YAML Configuration Files* section
199
199
  [--config-file-json or -cj CONFIG_FILE_JSON]
200
200
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -274,7 +274,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate schema
274
274
  [--service-account or -sa PATH_TO_SA_KEY]
275
275
  Service account to use for BigQuery result handler output.
276
276
  [--config-file or -c CONFIG_FILE]
277
- YAML Config File Path to be used for storing validations and other features.
277
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
278
278
  See: *Running DVT with YAML Configuration Files* section
279
279
  [--config-file-json or -cj CONFIG_FILE_JSON]
280
280
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -321,7 +321,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate custom-query col
321
321
  [--max COLUMNS] Comma separated list of columns for max or * for all numeric
322
322
  [--avg COLUMNS] Comma separated list of columns for avg or * for all numeric
323
323
  [--std COLUMNS] Comma separated list of columns for stddev_samp or * for all numeric
324
- [--exclude-columns or -ec]
324
+ [--exclude-columns or -ec]
325
325
  Flag to indicate the list of columns provided should be excluded and not included.
326
326
  [--bq-result-handler or -bqrh PROJECT_ID.DATASET.TABLE]
327
327
  BigQuery destination for validation results. Defaults to stdout.
@@ -329,7 +329,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate custom-query col
329
329
  [--service-account or -sa PATH_TO_SA_KEY]
330
330
  Service account to use for BigQuery result handler output.
331
331
  [--config-file or -c CONFIG_FILE]
332
- YAML Config File Path to be used for storing validations and other features.
332
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
333
333
  See: *Running DVT with YAML Configuration Files* section
334
334
  [--config-file-json or -cj CONFIG_FILE_JSON]
335
335
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -391,7 +391,7 @@ data-validation (--verbose or -v) (--log-level or -ll) validate custom-query row
391
391
  [--service-account or -sa PATH_TO_SA_KEY]
392
392
  Service account to use for BigQuery result handler output.
393
393
  [--config-file or -c CONFIG_FILE]
394
- YAML Config File Path to be used for storing validations and other features.
394
+ YAML Config File Path to be used for storing validations and other features. Supports GCS and local paths.
395
395
  See: *Running DVT with YAML Configuration Files* section
396
396
  [--config-file-json or -cj CONFIG_FILE_JSON]
397
397
  JSON Config File Path to be used for storing validations only for application purposes.
@@ -435,11 +435,10 @@ For example, this flag can be used as follows:
435
435
 
436
436
  Running DVT with YAML configuration files is the recommended approach if:
437
437
  * you want to customize the configuration for any given validation OR
438
- * you want to run DVT at scale (i.e. row validations across many partitions)
438
+ * you want to run DVT at scale (i.e. run multiple validations sequentially or in parallel)
439
439
 
440
- We recommend generating YAML configs with the `--config-file <file-name>` flag when running a validation command. The validation
441
- config file is saved to the GCS path specified by the `PSO_DV_CONFIG_HOME` env variable if that has been set;
442
- otherwise, it is saved to wherever the tool is run.
440
+ We recommend generating YAML configs with the `--config-file <file-name>` flag when running a validation command, which supports
441
+ GCS and local paths.
443
442
 
444
443
  You can use the `data-validation configs` command to run and view YAMLs.
445
444
 
@@ -452,7 +451,7 @@ data-validation (--verbose or -v) (--log-level or -ll) configs run
452
451
  [--dry-run or -dr] If this flag is present, prints the source and target SQL generated in lieu of running the validation.
453
452
  [--kube-completions or -kc]
454
453
  Flag to indicate usage in Kubernetes index completion mode.
455
- See *Scaling DVT to run 10's to 1000's of validations concurrently* section
454
+ See *Scaling DVT* section
456
455
  ```
457
456
 
458
457
  ```
@@ -470,19 +469,17 @@ View the complete YAML file for a Grouped Column validation on the
470
469
  [Examples](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/examples.md#sample-yaml-config-grouped-column-validation) page.
471
470
 
472
471
 
473
- #### Scaling DVT to run 10's to 1000's of validations concurrently
472
+ ### Scaling DVT
474
473
 
475
- As described above, you can run multiple validation configs sequentially with the `--config-dir` flag. To optimize the validation speed for large tables, you can run DVT concurrently using GKE Jobs ([Google Kubernetes Jobs](https://cloud.google.com/kubernetes-engine/docs/how-to/deploying-workloads-overview#batch_jobs)) or [Cloud Run Jobs](https://cloud.google.com/run/docs/create-jobs). If you are not familiar with Kubernetes or Cloud Run Jobs, see [Scaling DVT with Kubernetes](docs/internal/kubernetes_jobs.md) for a detailed overview.
474
+ You can scale DVT for large table validations by running the tool in a distributed manner. To optimize the validation speed for large tables, you can use GKE Jobs ([Google Kubernetes Jobs](https://cloud.google.com/kubernetes-engine/docs/how-to/deploying-workloads-overview#batch_jobs)) or [Cloud Run Jobs](https://cloud.google.com/run/docs/create-jobs). If you are not familiar with Kubernetes or Cloud Run Jobs, see [Scaling DVT with Distributed Jobs](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/internal/distributed_jobs.md) for a detailed overview.
476
475
 
477
- In order to validate partitions concurrently, both the `--kube-completions` and `--config-dir` flags are required. The `--kube-completions` flag specifies that the validation is being run in indexed completion mode in Kubernetes or as multiple independent tasks in Cloud Run. The `--config-dir` flag will specify the directory with the YAML files to be executed in parallel. If you used `generate-table-partitions` to generate the YAMLs, this would be the directory where the partition files numbered `0000.yaml` to `<partition_num - 1>.yaml` are stored i.e (`my_config_dir/source_schema.source_table/`)
478
476
 
479
- In order to run DVT in a container, you have to build a Docker image - [see instructions here](https://github.com/GoogleCloudPlatform/professional-services-data-validator/tree/develop/samples/docker#readme). You will also need to set the `PSO_DV_CONFIG_HOME` environment variable to point to a GCS prefix where the connection configuration files are stored. In Cloud Run you can use the option `--set-env-vars` or `--update-env-vars` to pass [the environment variable](https://cloud.google.com/run/docs/configuring/services/environment-variables#setting). We recommend that you use the `bq-result-handler` to save your validation results to BigQuery.
477
+ We recommend first generating table partitions with the `generate-table-partitions` command for your large tables. Then, use Cloud Run or GKE to distribute validating each chunk in parallel. See the [Cloud Run Jobs Quickstart sample](https://github.com/GoogleCloudPlatform/professional-services-data-validator/tree/develop/samples/cloud_run_jobs) to get started.
480
478
 
481
- The Cloud Run and Kubernetes pods must run in a network with access to the database servers. Every Cloud Run job is associated with a [service account](https://cloud.google.com/run/docs/securing/service-identity). You need to ensure that this service account has access to Google Cloud Storage (to read connection configuration and YAML files) and BigQuery (to publish results). If you are using Kubernetes, you will need to use a service account with the same privileges as mentioned for Cloud Run. In Kubernetes, you will need to set up [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) so the DVT container can impersonate the service account.
479
+ When running DVT in a distributed fashion, both the `--kube-completions` and `--config-dir` flags are required. The `--kube-completions` flag specifies that the validation is being run in indexed completion mode in Kubernetes or as multiple independent tasks in Cloud Run. If the `-kc` option is used and you are not running in indexed mode, you will receive a warning and the container will process all the validations sequentially. If the `-kc` option is used and a config directory is not provided (i.e. a `--config-file` is provided instead), a warning is issued.
482
480
 
483
- In Cloud Run, the [job](https://cloud.google.com/run/docs/create-jobs) must be run as multiple, independent tasks with the task count set to the number of partitions generated. In Kubernetes, set the number of completions to the number of partitions generated - see [Kubernetes Parallel Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/job/#parallel-jobs). The option `--kube-completions or -kc` tells DVT that many DVT containers are running in a Kubernetes cluster. Each DVT container only validates the specific partition YAML (based on the index assigned by Kubernetes control plane). If the `-kc` option is used and you are not running in indexed mode, you will receive a warning and the container will process all the validations sequentially. If the `-kc` option is used and a config directory is not provided (a `--config-file` is provided instead), a warning is issued.
481
+ The `--config-dir` flag will specify the directory with the YAML files to be executed in parallel. If you used `generate-table-partitions` to generate the YAMLs, this would be the directory where the partition files numbered `0000.yaml` to `<partition_num - 1>.yaml` are stored i.e (`gs://my_config_dir/source_schema.source_table/`). When creating your Cloud Run Job, set the number of tasks equal to the number of table partitions so the task index matches the YAML file to be validated. When executed, each Cloud Run task will validate a partition in parallel.
484
482
 
485
- By default, each partition validation is retried up to 3 times if there is an error. In Kubernetes and Cloud Run, you can set the parallelism to the number you want. Keep in mind that if you are validating 1000's of partitions in parallel, you may find that setting the parallelism too high (say 100) may result in timeouts and slow down the validation.
486
483
 
487
484
  ### Validation Reports
488
485
 
@@ -587,7 +584,8 @@ with calculated fields as shown in [this example](https://github.com/GoogleCloud
587
584
 
588
585
  Filters let you apply a WHERE statement to your validation query (ie. `SELECT *
589
586
  FROM table WHERE created_at > 30 days ago AND region_id = 71;`). The filter is
590
- written in the syntax of the given source.
587
+ written in the syntax of the given source and must reference columns in the
588
+ underlying table, not projected DVT expressions.
591
589
 
592
590
  Note that you are writing the query to execute, which does not have to match
593
591
  between source and target as long as the results can be expected to align. If
@@ -48,7 +48,10 @@ def _get_arg_config_file(args):
48
48
  """Return String YAML config file path."""
49
49
  if not args.config_file:
50
50
  raise ValueError("YAML Config File was not supplied.")
51
-
51
+ elif not args.config_file.endswith(".yaml"):
52
+ raise ValueError(
53
+ f"Invalid YAML config name: {args.config_file}. Provide YAML file extension."
54
+ )
52
55
  return args.config_file
53
56
 
54
57
 
@@ -56,7 +59,10 @@ def _get_arg_config_file_json(args):
56
59
  """Return String JSON config file path."""
57
60
  if not args.config_file_json:
58
61
  raise ValueError("JSON Config File was not supplied.")
59
-
62
+ elif not args.config_file_json.endswith(".json"):
63
+ raise ValueError(
64
+ f"Invalid JSON config name: {args.config_file_json}. Provide JSON file extension."
65
+ )
60
66
  return args.config_file_json
61
67
 
62
68
 
@@ -350,16 +356,17 @@ def config_runner(args):
350
356
  setattr(args, "config_dir", None)
351
357
  setattr(args, "config_file", config_file_path)
352
358
  config_managers = build_config_managers_from_yaml(args, config_file_path)
359
+ run_validations(args, config_managers)
353
360
  else:
354
361
  if args.kube_completions:
355
362
  logging.warning(
356
363
  "--kube-completions or -kc specified, however not running in Kubernetes Job completion, check your command line."
357
364
  )
358
- mgr = state_manager.StateManager(file_system_root_path=args.config_dir)
359
- config_file_names = mgr.list_validations_in_dir(args.config_dir)
365
+ config_file_names = cli_tools.list_validations(config_dir=args.config_dir)
360
366
  config_managers = []
361
367
  for file in config_file_names:
362
- config_managers.extend(build_config_managers_from_yaml(args, file))
368
+ config_managers = build_config_managers_from_yaml(args, file)
369
+ run_validations(args, config_managers)
363
370
  else:
364
371
  if args.kube_completions:
365
372
  logging.warning(
@@ -367,13 +374,12 @@ def config_runner(args):
367
374
  )
368
375
  config_file_path = _get_arg_config_file(args)
369
376
  config_managers = build_config_managers_from_yaml(args, config_file_path)
370
-
371
- run_validations(args, config_managers)
377
+ run_validations(args, config_managers)
372
378
 
373
379
 
374
380
  def build_config_managers_from_yaml(args, config_file_path):
375
381
  """Returns List[ConfigManager] instances ready to be executed."""
376
- if "config_dir" in args and args.config_dir:
382
+ if args.config_dir:
377
383
  yaml_configs = cli_tools.get_validation(config_file_path, args.config_dir)
378
384
  else:
379
385
  yaml_configs = cli_tools.get_validation(config_file_path)
@@ -616,7 +622,7 @@ def store_json_config_file(args, config_managers):
616
622
  """
617
623
  json_config = convert_config_to_json(config_managers)
618
624
  config_file_path = _get_arg_config_file_json(args)
619
- cli_tools.store_validation_json(config_file_path, json_config)
625
+ cli_tools.store_validation(config_file_path, json_config)
620
626
 
621
627
 
622
628
  def partition_and_store_config_files(args: Namespace) -> None:
@@ -673,7 +679,7 @@ def run_validation_configs(args):
673
679
  config_runner(args)
674
680
  elif args.validation_config_cmd == "list":
675
681
  config_dir = args.config_dir or "./"
676
- cli_tools.list_validations(config_dir=config_dir)
682
+ cli_tools.print_validations_in_dir(config_dir=config_dir)
677
683
  elif args.validation_config_cmd == "get":
678
684
  # Get and print yaml file config.
679
685
  yaml = cli_tools.get_validation(_get_arg_config_file(args))
@@ -49,10 +49,12 @@ import json
49
49
  import logging
50
50
  import sys
51
51
  import uuid
52
+ import os
52
53
  from argparse import Namespace
53
54
  from typing import Dict, List
55
+ from yaml import Dumper, Loader, dump, load
54
56
 
55
- from data_validation import clients, consts, state_manager
57
+ from data_validation import clients, consts, state_manager, gcs_helper
56
58
 
57
59
  CONNECTION_SOURCE_FIELDS = {
58
60
  "BigQuery": [
@@ -1081,47 +1083,46 @@ def get_connection(connection_name):
1081
1083
  return mgr.get_connection_config(connection_name)
1082
1084
 
1083
1085
 
1084
- def store_validation(validation_file_name, yaml_config):
1085
- """Store the validation YAML config under the given name."""
1086
- mgr = state_manager.StateManager()
1087
- mgr.create_validation_yaml(validation_file_name, yaml_config)
1088
-
1089
-
1090
- def store_validation_json(validation_file_name, json_config):
1091
- """Store the validation JSON config under the given name."""
1092
- mgr = state_manager.StateManager()
1093
- mgr.create_validation_json(validation_file_name, json_config)
1086
+ def store_validation(validation_file_name, config, include_log=True):
1087
+ """Store the validation config under the given name."""
1088
+ validation_path = gcs_helper.get_validation_path(validation_file_name)
1094
1089
 
1090
+ if validation_file_name.endswith(".yaml"):
1091
+ config_str = dump(config, Dumper=Dumper)
1092
+ elif validation_file_name.endswith("json"):
1093
+ config_str = json.dumps(config)
1094
+ else:
1095
+ raise ValueError(f"Invalid validation file name: {validation_file_name}")
1095
1096
 
1096
- def store_partition(target_file_path, yaml_config, target_folder_path=None):
1097
- """Store the partition YAML config under the given name."""
1098
- mgr = state_manager.StateManager(target_folder_path)
1099
- mgr.create_partition_yaml(target_file_path, yaml_config)
1097
+ gcs_helper.write_file(validation_path, config_str, include_log=include_log)
1100
1098
 
1101
1099
 
1102
- def get_validation(validation_name, config_dir=None):
1103
- """Return validation YAML for a specific connection."""
1100
+ def get_validation(name: str, config_dir: str = None):
1101
+ """Return validation YAML config."""
1104
1102
  if config_dir:
1105
- mgr = state_manager.StateManager(file_system_root_path=config_dir)
1106
- return mgr.get_validation_config(validation_name, config_dir)
1103
+ validation_path = os.path.join(config_dir, name)
1107
1104
  else:
1108
- if validation_name.startswith("gs://"):
1109
- obj_depth = len(validation_name.split("/"))
1110
- gcs_prefix = "/".join(validation_name.split("/")[: obj_depth - 1])
1111
- mgr = state_manager.StateManager(file_system_root_path=gcs_prefix)
1112
- return mgr.get_validation_config(
1113
- validation_name.split("/")[obj_depth - 1], gcs_prefix
1114
- )
1115
- else:
1116
- mgr = state_manager.StateManager()
1117
- return mgr.get_validation_config(validation_name)
1105
+ validation_path = gcs_helper.get_validation_path(name)
1106
+
1107
+ validation_bytes = gcs_helper.read_file(validation_path)
1108
+ return load(validation_bytes, Loader=Loader)
1118
1109
 
1119
1110
 
1120
1111
  def list_validations(config_dir="./"):
1121
- """List all saved validation YAMLs."""
1122
- mgr = state_manager.StateManager(file_system_root_path=config_dir)
1123
- validations = mgr.list_validations_in_dir(config_dir=config_dir)
1112
+ """List all saved validation YAMLs in a directory."""
1113
+ logging.info(f"Looking for validations in path {config_dir}")
1114
+ if gcs_helper._is_gcs_path(config_dir):
1115
+ if not config_dir.endswith("/"):
1116
+ config_dir += "/"
1117
+ files = gcs_helper.list_gcs_directory(config_dir)
1118
+ else:
1119
+ files = os.listdir(config_dir)
1120
+
1121
+ return [file_name for file_name in files if file_name.endswith(".yaml")]
1122
+
1124
1123
 
1124
+ def print_validations_in_dir(config_dir="./"):
1125
+ validations = list_validations(config_dir=config_dir)
1125
1126
  logging.info("Validation YAMLs found:")
1126
1127
  for validation_name in validations:
1127
1128
  logging.info(validation_name)
@@ -14,19 +14,17 @@
14
14
 
15
15
  import copy
16
16
  import logging
17
- from typing import Optional, Union, TYPE_CHECKING
18
- import yaml
17
+ from typing import TYPE_CHECKING, Optional, Union
19
18
 
20
19
  import google.oauth2.service_account
21
-
22
20
  import ibis.expr.datatypes as dt
21
+ import yaml
23
22
 
24
- from data_validation import clients, consts, state_manager
23
+ from data_validation import clients, consts, gcs_helper, state_manager
25
24
  from data_validation.result_handlers.bigquery import BigQueryResultHandler
26
25
  from data_validation.result_handlers.text import TextResultHandler
27
26
  from data_validation.validation_builder import ValidationBuilder
28
27
 
29
-
30
28
  if TYPE_CHECKING:
31
29
  import ibis.expr.types.TableExpr
32
30
 
@@ -322,9 +320,8 @@ class ConfigManager(object):
322
320
  allow_list = allow_list.replace(" ", "")
323
321
  full_allow_list.append(allow_list)
324
322
  if allow_list_file:
325
- mgr = state_manager.StateManager(file_system_root_path=allow_list_file)
326
323
  try:
327
- allow_list_yaml = mgr.read_file(allow_list_file)
324
+ allow_list_yaml = gcs_helper.read_file(allow_list_file)
328
325
  except FileNotFoundError as e:
329
326
  raise ValueError(
330
327
  "Cannot locate --allow-list-file: {allow_list_file}"
@@ -543,7 +540,7 @@ class ConfigManager(object):
543
540
  ].type()
544
541
  cast_type = (
545
542
  "string"
546
- if self._decimal_column_too_big_for_pandas(
543
+ if self._key_column_needs_casting_to_string(
547
544
  source_ibis_type, target_ibis_type
548
545
  )
549
546
  else None
@@ -695,6 +692,19 @@ class ConfigManager(object):
695
692
  )
696
693
  )
697
694
 
695
+ def _key_column_needs_casting_to_string(
696
+ self,
697
+ source_column_ibis_type: dt.DataType,
698
+ target_column_ibis_type: dt.DataType,
699
+ ) -> bool:
700
+ return bool(
701
+ self._decimal_column_too_big_for_pandas(
702
+ source_column_ibis_type, target_column_ibis_type
703
+ )
704
+ or isinstance(source_column_ibis_type, dt.Binary)
705
+ or isinstance(target_column_ibis_type, dt.Binary)
706
+ )
707
+
698
708
  def build_config_column_aggregates(
699
709
  self, agg_type, arg_value, exclude_cols, supported_types, cast_to_bigint=False
700
710
  ):
@@ -99,7 +99,7 @@ CONFIG_TYPES = [
99
99
 
100
100
  # State Manager Fields
101
101
  DEFAULT_ENV_DIRECTORY = "~/.config/google-pso-data-validator/"
102
- ENV_DIRECTORY_VAR = "PSO_DV_CONFIG_HOME"
102
+ ENV_DIRECTORY_VAR = "PSO_DV_CONN_HOME"
103
103
 
104
104
  # Yaml File Config Fields
105
105
  YAML_RESULT_HANDLER = "result_handler"
@@ -106,10 +106,15 @@ class DataValidation(object):
106
106
  raise ValueError("Primary Keys are required for Random Row Filters")
107
107
 
108
108
  # Filter for only first primary key (multi-pk filter not supported)
109
- primary_key_info = self.config_manager.primary_keys[0]
109
+ source_pk_column = self.config_manager.primary_keys[0][
110
+ consts.CONFIG_SOURCE_COLUMN
111
+ ]
112
+ target_pk_column = self.config_manager.primary_keys[0][
113
+ consts.CONFIG_TARGET_COLUMN
114
+ ]
110
115
 
111
116
  randomRowBuilder = RandomRowBuilder(
112
- [primary_key_info[consts.CONFIG_SOURCE_COLUMN]],
117
+ [source_pk_column],
113
118
  self.config_manager.random_row_batch_size(),
114
119
  )
115
120
 
@@ -128,24 +133,33 @@ class DataValidation(object):
128
133
  self.validation_builder.source_builder,
129
134
  )
130
135
 
136
+ # Check if source table's primary key is BINARY, if so then
137
+ # force cast the id columns to STRING (HEX).
138
+ binary_conversion_required = False
139
+ if query[source_pk_column].type().is_binary():
140
+ binary_conversion_required = True
141
+ query = query.mutate(
142
+ **{source_pk_column: query[source_pk_column].cast("string")}
143
+ )
144
+
131
145
  random_rows = self.config_manager.source_client.execute(query)
132
146
  if len(random_rows) == 0:
133
147
  return
148
+
149
+ random_values = list(random_rows[source_pk_column])
150
+ if binary_conversion_required:
151
+ # For binary ids we have a list of hex strings for our IN list.
152
+ # Each of these needs to be cast back to binary.
153
+ random_values = [ibis.literal(_).cast("binary") for _ in random_values]
154
+
134
155
  filter_field = {
135
156
  consts.CONFIG_TYPE: consts.FILTER_TYPE_ISIN,
136
- consts.CONFIG_FILTER_SOURCE_COLUMN: primary_key_info[
137
- consts.CONFIG_FIELD_ALIAS
138
- ],
139
- consts.CONFIG_FILTER_SOURCE_VALUE: random_rows[
140
- primary_key_info[consts.CONFIG_SOURCE_COLUMN]
141
- ],
142
- consts.CONFIG_FILTER_TARGET_COLUMN: primary_key_info[
143
- consts.CONFIG_FIELD_ALIAS
144
- ],
145
- consts.CONFIG_FILTER_TARGET_VALUE: random_rows[
146
- primary_key_info[consts.CONFIG_SOURCE_COLUMN]
147
- ],
157
+ consts.CONFIG_FILTER_SOURCE_COLUMN: source_pk_column,
158
+ consts.CONFIG_FILTER_SOURCE_VALUE: random_values,
159
+ consts.CONFIG_FILTER_TARGET_COLUMN: target_pk_column,
160
+ consts.CONFIG_FILTER_TARGET_VALUE: random_values,
148
161
  }
162
+
149
163
  self.validation_builder.add_filter(filter_field)
150
164
 
151
165
  def query_too_large(self, rows_df, grouped_fields):