API reference¶
This page documents every public-facing class, function, and enum exported by the valentine package. For task-oriented guides see Getting started, Matchers, Matcher results, and Evaluation metrics.
Jump to section
Core · ColumnPair · MatcherResults · InvalidMatcherError · Matchers · Metrics · Data sources
The top-level package exports:
from valentine import (
valentine_match, # main entry point
ColumnPair, # NamedTuple key for matches
MatcherResults, # immutable Mapping returned by valentine_match
InvalidMatcherError, # raised for invalid matcher arguments
)
valentine_match¶
Match columns across DataFrames.
Accepts any iterable of DataFrames (pandas or Polars) and matches columns across all unique pairs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dfs | Iterable[DataFrame | DataFrame] | Two or more DataFrames to match against each other. Pandas and Polars frames may be mixed freely within the same call. | required |
matcher | BaseMatcher | The matching algorithm to use. | required |
df_names | list[str] | None | Optional names for each DataFrame. If not provided, defaults to "aaa", "bbb", etc. | None |
instance_sample_size | int | None | Optional max number of non-empty rows to use for instance-based sampling in matchers like Coma. If None, no sampling is applied. | 1000 |
Returns:
| Type | Description |
|---|---|
MatcherResults | Immutable mapping of |
Raises:
| Type | Description |
|---|---|
ValueError | If fewer than 2 DataFrames are provided, or if |
InvalidMatcherError | If |
Examples:
Match two pandas DataFrames:
Match Polars DataFrames:
Match multiple DataFrames (computes all pairs):
Inspect sub-matcher breakdowns (Coma only):
ColumnPair¶
Bases: NamedTuple
A matched pair of columns from two tables.
Immutable, hashable key identifying a matched pair of columns. Used everywhere a match result or ground truth entry is required. Because it is a NamedTuple, it also supports positional indexing, iteration, and unpacking::
pair = ColumnPair("orders", "price", "sales", "amount")
pair.source_table # "orders"
pair.source_column # "price"
pair.target_table # "sales"
pair.target_column # "amount"
pair.source # ("orders", "price")
pair.target # ("sales", "amount")
st, sc, tt, tc = pair # positional unpacking
Attributes:
| Name | Type | Description |
|---|---|---|
source_table | str | Name of the source table. |
source_column | str | Name of the source column. |
target_table | str | Name of the target table. |
target_column | str | Name of the target column. |
MatcherResults¶
Bases: Mapping
Immutable mapping of ColumnPair to similarity scores.
Returned by valentine_match and individual matcher methods. Results are sorted from highest to lowest similarity and cannot be mutated after creation (preventing accidental invalidation of cached derived views like one_to_one).
Aside from standard mapping operations (len, iteration, indexing), provides convenience methods for filtering, subsetting, and computing evaluation metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
matches | dict[ColumnPair, float] | Raw match scores. | required |
details | dict[ColumnPair, dict[str, float]] | None | Optional per-pair breakdown of sub-matcher scores (e.g. from Coma). | None |
Mapping protocol¶
| Operation | Behaviour |
|---|---|
len(results) | Number of matches. |
iter(results) | Iterate ColumnPair keys in descending score order. |
results[pair] | Look up the similarity score for a given ColumnPair. |
pair in results | Check membership. |
results.items() | Yield (ColumnPair, float) pairs in descending score order. |
results == other | Equality with another MatcherResults or a plain dict[ColumnPair, float]. |
MatcherResults is not hashable (__hash__ is None).
Details¶
details¶
Per-pair sub-matcher score breakdowns.
When the matcher provides component scores (e.g. Coma's name, path, leaves, parents, instances matchers), this maps each ColumnPair to {matcher_name: score}.
Returns an empty dict when the matcher does not provide details.
get_details¶
Get the sub-matcher breakdown for a specific column pair.
Returns None if no details are available for the given pair.
Transformations¶
All transformations return a new MatcherResults instance; the original is left untouched. Sub-matcher details are carried over to the filtered subset.
one_to_one_hungarian¶
Globally optimal 1:1 column matching via Hungarian assignment.
This is the default 1:1 selector — it is what Precision / Recall / F1Score call when their one_to_one flag is set. Each source and target appears in at most one returned pair, with the assignment chosen to maximise total similarity over all valid one-to-one assignments. Cost is O(n³) on column counts via scipy.optimize.linear_sum_assignment — negligible for typical schema sizes — and almost always strictly better than the greedy variant.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold | float | None | Minimum similarity to keep. If | None |
Returns:
| Type | Description |
|---|---|
MatcherResults | A new instance with the Hungarian-optimal one-to-one assignment, post-thresholding. |
one_to_one_greedy¶
Greedy 1:1 column matching, kept for backwards compatibility.
Starting from the highest-scoring pair, greedily assigns each source and target column at most one match. Pairs below threshold are discarded. When threshold is None (the default), the median similarity score is used.
Greedy can lock in a locally-best pair that blocks a better globally-optimal assignment, so one_to_one_hungarian is the recommended default; this method is exposed for compatibility and for test pinning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold | float | None | Minimum similarity to keep. If | None |
Returns:
| Type | Description |
|---|---|
MatcherResults | A new instance with the greedy 1:1 assignment. |
one_to_one_mutual_top¶
Keep pairs where each side ranks the other in its top n.
Pair (s, t) survives iff t is among s's n highest- scoring targets AND s is among t's n highest-scoring sources. With n=1 this is the classic mutual nearest- neighbour filter — high-precision, drops one-sided affinities. Strictly stricter than one_to_one_hungarian: only mutually-confirmed pairs survive, even at the cost of recall.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n | int | Top-n cutoff per side (default 1 = mutual nearest neighbour). | 1 |
Returns:
| Type | Description |
|---|---|
MatcherResults | A new instance with only the mutually-confirmed pairs. |
filter¶
Filter matches by minimum similarity score.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_score | float | Minimum similarity score to keep. | required |
Returns:
| Type | Description |
|---|---|
MatcherResults | A new instance containing only matches with score >= min_score. |
take_top_n¶
Keep the top n matches by score.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n | int | Number of matches to keep. | required |
Returns:
| Type | Description |
|---|---|
MatcherResults | A new instance with only the top |
take_top_percent¶
Keep the top percent% of matches by score.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
percent | int | Percentage of matches to keep (0-100). | required |
Returns:
| Type | Description |
|---|---|
MatcherResults | A new instance with only the top matches. |
take_top_n_per_source¶
Keep the top n matches per source column.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n | int | Number of matches to keep per source column. | required |
Returns:
| Type | Description |
|---|---|
MatcherResults | A new instance with only the top |
get_copy¶
Return a shallow copy of this instance.
Metrics¶
get_metrics¶
Compute evaluation metrics against a ground truth.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ground_truth | list[tuple[str, str]] | list[ColumnPair] | Expected column matches. Can be simple column-name pairs like | required |
metrics | set[Metric] | Set of metric instances to compute (default: | METRICS_CORE |
one_to_one_method | ('greedy', 'hungarian', 'mutual_top') | Selection algorithm passed to each metric's | "greedy" |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | Metric name to score mapping. |
InvalidMatcherError¶
Bases: Exception
Raised when a non-BaseMatcher object is passed as a matcher.
Deprecated alias
NotAValentineMatcher is kept as an alias for backward compatibility with pre-1.0 code and will be removed in a future release. New code should catch InvalidMatcherError directly.
Match (internal)¶
valentine.algorithms.match.Match is an internal dataclass used by matchers to build up result entries before they are merged into a dict[ColumnPair, float]. It is intentionally not re-exported from the top-level package and should not be used in user code — ColumnPair is the stable, public key type.
Matchers (valentine.algorithms)¶
Every matcher extends the abstract BaseMatcher class. The module exports:
from valentine.algorithms import (
BaseMatcher,
Coma,
Cupid,
DistributionBased,
JaccardDistanceMatcher,
SimilarityFlooding,
# Enums used by the matchers:
Formula, Policy, StringMatcher,
# Groupings:
schema_only_algorithms,
instance_only_algorithms,
schema_instance_algorithms,
all_matchers,
# Key types:
ColumnPair,
)
The groupings are plain lists of class names:
| Constant | Contents |
|---|---|
schema_only_algorithms | ["SimilarityFlooding", "Cupid"] |
instance_only_algorithms | ["DistributionBased", "JaccardDistanceMatcher"] |
schema_instance_algorithms | ["Coma"] |
all_matchers | Union of the three lists above. |
BaseMatcher¶
Abstract base. Subclasses must implement get_matches; get_matches_batch has a default fall-back that calls get_matches on each unique pair.
Bases: ABC
Abstract base class for every matching algorithm.
Subclasses must implement get_matches. get_matches_batch has a default fall-back that calls get_matches on each unique pair of tables; override it in subclasses that benefit from a holistic view of all tables (e.g. a global TF-IDF corpus or global distribution ranks).
get_matches¶
Match columns between two tables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_input | BaseTable | The source table. | required |
target_input | BaseTable | The target table. | required |
Returns:
| Type | Description |
|---|---|
dict | Mapping of |
get_matches_batch¶
Match columns across all unique pairs of tables.
The default implementation calls get_matches for each pair independently. Algorithms that benefit from a holistic view of all tables (e.g. global TF-IDF corpus, global distribution ranks) can override this method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tables | list[BaseTable] | Two or more tables to match. | required |
Returns:
| Type | Description |
|---|---|
dict | Combined matches across all pairs. |
match_details¶
Per-pair score breakdowns from the most recent match call.
Returns a mapping from ColumnPair to a dictionary of {matcher_name: score} showing how each sub-matcher contributed to the final similarity. Empty by default; override in subclasses that combine multiple matchers (e.g. Coma).
Coma¶
Bases: BaseMatcher
Pure Python implementation of the COMA 3.0 schema matching algorithm.
COMA (COmbination of MAtching algorithms) works by composing multiple individual matchers — each targeting a different aspect of schema or data similarity — and combining their scores. This implementation faithfully reproduces the matching pipeline from the original Java COMA 3.0 Community Edition.
Schema matchers (enabled by use_schema=True, the default):
- Name: trigram (Dice) similarity on column names.
- Path: trigram similarity on dot-separated schema paths.
- Leaves: name similarity across all leaf-level columns.
- Parents: structural similarity via parent-level leaf comparison.
Instance matcher (enabled by use_instances=True):
- TF-IDF cosine similarity: each cell value is treated as a document, a global IDF is computed across all columns of both tables, and per-column similarity is aggregated using a max-matching Dice formula.
The two groups can be used independently or together. At least one of use_schema or use_instances must be enabled.
After computing all-pairs similarity scores, a selection step filters results using bidirectional best-match logic (DIR_BOTH) controlled by max_n, delta, and threshold.
When matching more than two tables via get_matches_batch, the TF-IDF corpus is built once from all tables, giving each pair the benefit of global IDF statistics.
Populates MatcherResults.details with {name, path, leaves, parents, instances} sub-scores.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_n | int | Maximum number of matches to keep per column. | 0 |
use_instances | bool | Enable TF-IDF instance-based matching (default: False). | False |
use_schema | bool | Enable schema-based matching (default: True). At least one of | True |
delta | float | Fraction from the best per-column score within which matches are kept. For example, 0.15 keeps all matches scoring within 15% of the best match for that column. Must be in | 0.15 |
threshold | float | Absolute minimum similarity score to keep a match. Must be in | 0.0 |
instance_weight | float | Weight for the instance matcher relative to schema matchers (which always have weight 1.0). Must be | 1.0 |
Cupid¶
Bases: BaseMatcher
Python implementation of the Cupid schema matching algorithm.
Cupid combines linguistic similarity of column names with structural similarity derived from schema tree shape, following the paper Generic Schema Matching with Cupid (Madhavan et al., VLDB 2001).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
leaf_w_struct | float | Weight of structural similarity at leaf level, in | 0.2 |
w_struct | float | Weight of structural similarity at inner-node level, in | 0.2 |
th_accept | float | Acceptance similarity threshold for the final mapping, in | 0.7 |
th_high | float | High-confidence threshold used during structural propagation, in | 0.6 |
th_low | float | Low-confidence threshold used during structural propagation, in | 0.35 |
c_inc | float | Positive reinforcement coefficient for matching children (must be | 1.2 |
c_dec | float | Negative reinforcement coefficient for non-matching children (must be | 0.9 |
th_ns | float | Name-similarity threshold, in | 0.7 |
process_num | int | Number of worker processes (must be | 1 |
DistributionBased¶
Bases: BaseMatcher
Distribution-based column matching.
Implementation of the algorithm from Automatic Discovery of Attributes in Relational Databases (Zhang et al., SIGMOD 2011). Columns are compared by quantile histograms of their value distributions; Earth Mover's Distance drives the ranking of matches within each cluster.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold1 | float | Distance threshold used in phase 1 (distribution clustering), in | 0.15 |
threshold2 | float | Distance threshold used in phase 2 (attribute clustering), in | 0.15 |
quantiles | int | Number of quantiles used for histogram summaries (must be | 256 |
process_num | int | Number of worker processes (must be | 1 |
use_bloom_filters | bool | When | False |
JaccardDistanceMatcher¶
Bases: BaseMatcher
Baseline instance-based matcher using Jaccard similarity.
Columns are compared by Jaccard similarity of their value sets, with element equality decided by a configurable string distance function. This is a simple but effective baseline for instance-based matching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold_dist | float | Acceptance threshold above which two string values are considered equal under the chosen | 0.8 |
distance_fun | StringDistanceFunction | String similarity function. One of | Levenshtein |
process_num | int | Number of worker threads passed to | 1 |
embedding_model | str | Name of the sentence-transformers model used when | 'all-MiniLM-L6-v2' |
embedding_device | str or None | Device to load the embedding model on. Passed straight through to | None |
embedding_batch_size | int or None | Batch size used for the global | None |
tversky_alpha | float | Tversky penalty for unmatched values on the reference side (default: | 1.0 |
tversky_beta | float | Tversky penalty for unmatched values on the other side (default: | 1.0 |
StringDistanceFunction¶
Bases: Enum
Element-equality functions supported by JaccardDistanceMatcher.
Levenshtein class-attribute instance-attribute ¶
Normalized Levenshtein ratio (default).
DamerauLevenshtein class-attribute instance-attribute ¶
Normalized Damerau-Levenshtein ratio.
Hamming class-attribute instance-attribute ¶
Normalized Hamming distance (strings of equal length).
Exact class-attribute instance-attribute ¶
Exact string equality (forces the threshold to 1.0).
Embedding class-attribute instance-attribute ¶
Cosine similarity of sentence-transformer embeddings. Requires the sentence-transformers extra (pip install valentine[embeddings]).
from valentine.algorithms.jaccard_distance import StringDistanceFunction
from valentine.algorithms import JaccardDistanceMatcher
m = JaccardDistanceMatcher(
threshold_dist=0.9,
distance_fun=StringDistanceFunction.JaroWinkler,
)
SimilarityFlooding¶
Bases: BaseMatcher
Python implementation of the Similarity Flooding schema matcher.
Similarity Flooding (Melnik, Garcia-Molina, Rahm — ICDE 2002) treats each schema as a labelled graph and iteratively propagates an initial element-level similarity across the graph structure until a fixpoint is reached.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coeff_policy | Policy | Coefficient policy for the propagation graph. One of | INVERSE_AVERAGE |
formula | Formula | Fixpoint iteration formula. One of | FORMULA_C |
string_matcher | StringMatcher | String similarity function used for the initial element-level mapping. One of | PREFIX_SUFFIX |
tfidf_corpus | list[BaseTable] | None | Additional tables to include when computing IDF weights for the | None |
Policy¶
Formula¶
StringMatcher¶
Bases: Enum
String matching function for the initial similarity mapping.
PREFIX_SUFFIX class-attribute instance-attribute ¶
Prefix/suffix trigram matcher (default).
PREFIX_SUFFIX_TFIDF class-attribute instance-attribute ¶
Prefix/suffix matcher weighted by IDF computed from the corpus.
LEVENSHTEIN class-attribute instance-attribute ¶
Normalized Levenshtein similarity on node labels.
Metrics (valentine.metrics)¶
from valentine.metrics import (
Metric, # abstract base class
Precision,
Recall,
F1Score,
PrecisionTopNPercent,
RecallAtSizeofGroundTruth,
MeanReciprocalRank,
METRICS_CORE,
METRICS_ALL,
METRICS_PRECISION_RECALL,
METRICS_PRECISION_INCREASING_N,
)
Metric¶
Abstract base class (@dataclass(frozen=True)). Subclass to implement custom metrics:
@dataclass(eq=True, frozen=True)
class MyMetric(Metric):
threshold: float = 0.5
def apply(self, matches, ground_truth):
# ... compute score ...
return self.return_format(score)
apply¶
Apply the metric to a MatcherResults instance, given ground truth.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
matches | MatcherResults | The | required |
ground_truth | list | Expected column matches. Either column-name pairs | required |
one_to_one_method | ('greedy', 'hungarian', 'mutual_top') | Selection algorithm used when the metric's | "greedy" |
name¶
The name of the metric, as it appears in the metric results.
Returns:
| Type | Description |
|---|---|
str | The name of the metric. |
return_format¶
The return format of the apply method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value | Any | The metric value or score. | required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | The formatted metric value or score. |
Built-in metrics¶
All built-in metrics are @dataclass(frozen=True) and hashable, so they can live in the predefined metric sets.
Precision¶
Bases: Metric
Precision = TP / (TP + FP).
Attributes:
| Name | Type | Description |
|---|---|---|
one_to_one | bool | Whether to apply the one-to-one filter to the MatcherResults first. |
Recall¶
Bases: Metric
Recall = TP / (TP + FN).
Attributes:
| Name | Type | Description |
|---|---|---|
one_to_one | bool | Whether to apply the one-to-one filter to the MatcherResults first. |
F1Score¶
Bases: Metric
F1 score = 2 * (Precision * Recall) / (Precision + Recall).
Attributes:
| Name | Type | Description |
|---|---|---|
one_to_one | bool | Whether to apply the one-to-one filter to the MatcherResults first. |
PrecisionTopNPercent¶
Bases: Metric
Precision restricted to the top-N% of predicted matches by score.
Attributes:
| Name | Type | Description |
|---|---|---|
one_to_one | bool | Whether to apply the one-to-one filter to the MatcherResults first. |
n | int | Percentage of matches to consider (0-100). |
RecallAtSizeofGroundTruth¶
Bases: Metric
Recall when considering the top-|GT| predictions.
This simulates selecting as many predictions as there are gold pairs and computing recall at that cutoff: TP / (TP + FN) where the candidate set is the top-len(ground_truth) matches by score.
Attributes:
| Name | Type | Description |
|---|---|---|
one_to_one | bool | Whether to apply the one-to-one filter to the MatcherResults first. |
MeanReciprocalRank¶
Bases: Metric
Mean Reciprocal Rank (MRR).
For each ground truth pair, finds its rank (1-indexed position) in the matcher results sorted by descending score. The reciprocal rank is 1/rank if the pair is found, or 0 if absent. MRR is the mean of reciprocal ranks across all ground truth pairs.
Attributes:
| Name | Type | Description |
|---|---|---|
one_to_one | bool | Whether to apply the one-to-one filter to the MatcherResults first. |
Predefined metric sets¶
| Set | Contents |
|---|---|
METRICS_CORE | Precision, Recall, F1Score, PrecisionTopNPercent, RecallAtSizeofGroundTruth, MeanReciprocalRank (defaults). |
METRICS_ALL | Both one_to_one=True and one_to_one=False variants of Precision, Recall, F1Score, plus PrecisionTopNPercent, RecallAtSizeofGroundTruth, and MeanReciprocalRank. |
METRICS_PRECISION_RECALL | {Precision(), Recall()}. |
METRICS_PRECISION_INCREASING_N | PrecisionTopNPercent for n ∈ {10, 20, 30, …, 100}. |
Data sources (valentine.data_sources)¶
Valentine wraps each DataFrame in a DataframeTable (pandas) or PolarsTable (Polars) before handing it to a matcher. Most users never touch this layer — valentine_match auto-detects the frame type and builds the tables for you — but the classes are public so that custom matchers and custom data sources can be written against the abstractions.
from valentine.data_sources import (
BaseTable,
BaseColumn,
DataframeTable,
DataframeColumn,
)
# With the polars extra installed:
from valentine.data_sources import PolarsTable, PolarsColumn
BaseTable¶
Bases: ABC
Abstract class representing a table.
Subclasses wrap a concrete frame type (pandas DataFrame, Polars DataFrame, etc.) and expose its contents through a uniform column-oriented interface that the matching algorithms consume.
Abstract members (must be provided by subclasses):
Table name. Becomes source_table/target_table in emitted ColumnPair instances.
Stable identifier used internally to key per-table state.
All columns in the table.
Return the underlying frame object (pandas/Polars/…).
Whether the table has zero rows.
Concrete members (provided by BaseTable, override if needed):
Return the frame used for instance-based sampling. Defaults to get_df.
Return columns built from the instance-sampled frame. Defaults to get_columns.
Return a {column_name: column.unique_identifier} lookup.
Map a dtype string to a canonical Valentine type.
Recognises text-like types from both pandas (object, string, str) and Polars (Utf8, String, Categorical), as well as numeric and date categories.
BaseColumn¶
Bases: ABC
Abstract class representing a single column.
A BaseColumn knows its name, its values, and its detected data type. Implement this alongside BaseTable to plug a non-DataFrame backend into Valentine's matchers.
Abstract members:
Column name.
Stable identifier used internally to key per-column state.
Detected type: one of "varchar", "int", "float", or "date".
The column's values.
Concrete members:
Number of elements in data.
True when size is 0.
DataframeTable¶
Bases: BaseTable
A BaseTable backed by a pandas DataFrame.
The concrete implementation used by valentine_match. Automatic data-type detection classifies each column as "varchar", "int", "float", or "date" based on the DataFrame's dtype and content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df | DataFrame | The DataFrame to wrap. | required |
name | str | Name of the table. Used as | required |
instance_sample_size | int | None | Cap on the number of non-empty rows sampled per column. | 1000 |
DataframeColumn¶
Bases: BaseColumn
A BaseColumn adapter for a single pandas Series.
Constructed internally by DataframeTable; exposes the column name, detected data type, unique identifier, and sampled instance values via the standard BaseColumn interface.
PolarsTable¶
Bases: BaseTable
A BaseTable backed by a Polars DataFrame.
Drop-in replacement for DataframeTable; all matching algorithms work identically because they consume the BaseTable / BaseColumn interface, not the underlying frame type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df | DataFrame | The Polars DataFrame to wrap. | required |
name | str | A human-readable table name. | required |
instance_sample_size | int | None | Maximum number of non-empty rows kept for instance-based matchers. | 1000 |
PolarsColumn¶
Bases: BaseColumn
A BaseColumn adapter for a single Polars Series.
Constructed internally by PolarsTable; exposes the column name, detected data type, unique identifier, and sampled instance values via the standard BaseColumn interface.
Writing a custom data source¶
If your data doesn't live in a pandas DataFrame, implement BaseTable and BaseColumn directly. A minimal custom source just needs a name, a unique identifier, and the ability to enumerate its columns:
import uuid
import pandas as pd
from valentine import valentine_match
from valentine.algorithms import Coma
from valentine.data_sources import BaseColumn, BaseTable
class DictColumn(BaseColumn):
def __init__(self, name: str, data: list, data_type: str = "varchar"):
self._name = name
self._data = data
self._data_type = data_type
self._guid = str(uuid.uuid4())
@property
def name(self) -> str:
return self._name
@property
def unique_identifier(self) -> str:
return self._guid
@property
def data_type(self) -> str:
return self._data_type
@property
def data(self) -> list:
return self._data
class DictTable(BaseTable):
def __init__(self, name: str, columns: dict[str, list]):
self._name = name
self._guid = str(uuid.uuid4())
self._columns = [DictColumn(k, v) for k, v in columns.items()]
@property
def name(self) -> str:
return self._name
@property
def unique_identifier(self) -> str:
return self._guid
def get_columns(self) -> list[BaseColumn]:
return self._columns
def get_df(self) -> pd.DataFrame:
return pd.DataFrame({c.name: c.data for c in self._columns})
@property
def is_empty(self) -> bool:
return all(len(c.data) == 0 for c in self._columns)
# Matchers call get_matches / get_matches_batch directly on BaseTable
# instances, so custom sources bypass valentine_match:
source = DictTable("hr", {"emp_id": [1, 2, 3], "fname": ["a", "b", "c"]})
target = DictTable("payroll", {"employee_number": [1, 2, 3], "first_name": ["a", "b", "c"]})
raw = Coma().get_matches_batch([source, target])
If you want to reuse Valentine's instance-sampling logic, override get_instances_df to return a capped DataFrame. Custom sources are accepted by every built-in matcher — only valentine_match itself is DataFrame-specific.