lance.LanceDataset.merge_insert(开启: str | Iterable[str]) MergeInsertBuilder

返回一个构建器,可用于创建“合并插入”操作

该操作可以在单个事务中添加行、更新行和删除行。这是一个非常通用的工具,可用于实现诸如“如果不存在则插入”、“更新或插入(即upsert)”等行为,甚至可以用新数据替换部分现有数据(例如替换所有月份为“一月”的数据)。

合并插入操作通过使用连接将源表中的新数据与目标表中的现有数据相结合。记录分为三类。

"匹配"记录是指同时存在于源表和目标表中的记录。"未匹配"记录仅存在于源表中(例如这些是新数据)。"源未匹配"记录仅存在于目标表中(这是旧数据)。

此方法返回的构建器可用于自定义每种数据类别应执行的操作。

请注意,此操作会导致数据重新排序。这是因为更新的行会从数据集中删除,然后以新值重新插入到末尾。由于内部使用了哈希连接操作,新插入行的顺序可能会随机波动。

Parameters:
on : Union[str, Iterable[str]]

要连接的列(或多列)。这是源表和目标表中记录匹配的方式。通常这是某种键或ID列。

示例

使用when_matched_update_all()when_not_matched_insert_all()来执行"upsert"操作。这将更新数据集中已存在的行,并插入不存在的行。

>>> import lance
>>> import pyarrow as pa
>>> table = pa.table({"a": [2, 1, 3], "b": ["a", "b", "c"]})
>>> dataset = lance.write_dataset(table, "example")
>>> new_table = pa.table({"a": [2, 3, 4], "b": ["x", "y", "z"]})
>>> # Perform a "upsert" operation
>>> dataset.merge_insert("a")     \
...             .when_matched_update_all()     \
...             .when_not_matched_insert_all() \
...             .execute(new_table)
{'num_inserted_rows': 1, 'num_updated_rows': 2, 'num_deleted_rows': 0}
>>> dataset.to_table().sort_by("a").to_pandas()
   a  b
0  1  b
1  2  x
2  3  y
3  4  z

使用when_not_matched_insert_all()执行"不存在则插入"操作。这只会插入数据集中尚不存在的行。

>>> import lance
>>> import pyarrow as pa
>>> table = pa.table({"a": [1, 2, 3], "b": ["a", "b", "c"]})
>>> dataset = lance.write_dataset(table, "example2")
>>> new_table = pa.table({"a": [2, 3, 4], "b": ["x", "y", "z"]})
>>> # Perform an "insert if not exists" operation
>>> dataset.merge_insert("a")     \
...             .when_not_matched_insert_all() \
...             .execute(new_table)
{'num_inserted_rows': 1, 'num_updated_rows': 0, 'num_deleted_rows': 0}
>>> dataset.to_table().sort_by("a").to_pandas()
   a  b
0  1  a
1  2  b
2  3  c
3  4  z

您不需要提供所有列。如果只想更新部分列,可以省略不想更新的列。被省略的列在更新时会保留现有值,如果是插入操作则会设为null。

>>> import lance
>>> import pyarrow as pa
>>> table = pa.table({"a": [1, 2, 3], "b": ["a", "b", "c"], \
...                   "c": ["x", "y", "z"]})
>>> dataset = lance.write_dataset(table, "example3")
>>> new_table = pa.table({"a": [2, 3, 4], "b": ["x", "y", "z"]})
>>> # Perform an "upsert" operation, only updating column "a"
>>> dataset.merge_insert("a")     \
...             .when_matched_update_all()     \
...             .when_not_matched_insert_all() \
...             .execute(new_table)
{'num_inserted_rows': 1, 'num_updated_rows': 2, 'num_deleted_rows': 0}
>>> dataset.to_table().sort_by("a").to_pandas()
   a  b     c
0  1  a     x
1  2  x     y
2  3  y     z
3  4  z  None