|
49 | 49 | from quixstreams.sinks import BaseSink
|
50 | 50 | from quixstreams.state.base import State
|
51 | 51 | from quixstreams.state.base.transaction import PartitionTransaction
|
| 52 | +from quixstreams.state.rocksdb.timestamped import TimestampedStore |
52 | 53 | from quixstreams.utils.printing import (
|
53 | 54 | DEFAULT_COLUMN_NAME,
|
54 | 55 | DEFAULT_LIVE,
|
@@ -1604,6 +1605,27 @@ def concat(self, other: "StreamingDataFrame") -> "StreamingDataFrame":
|
1604 | 1605 | *self.topics, *other.topics, stream=merged_stream
|
1605 | 1606 | )
|
1606 | 1607 |
|
| 1608 | + def join(self, right: "StreamingDataFrame") -> "StreamingDataFrame": |
| 1609 | + # TODO: ensure copartitioning of left and right? |
| 1610 | + right.processing_context.state_manager.register_store( |
| 1611 | + stream_id=right.stream_id, |
| 1612 | + store_type=TimestampedStore, |
| 1613 | + changelog_config=self._topic_manager.derive_topic_config(right.topics), |
| 1614 | + ) |
| 1615 | + |
| 1616 | + def left_func(value, key, timestamp, headers): |
| 1617 | + right_tx = _get_transaction(right) |
| 1618 | + right_value = right_tx.get(timestamp=timestamp, prefix=key) |
| 1619 | + return {**value, **(right_value or {})} |
| 1620 | + |
| 1621 | + def right_func(value, key, timestamp, headers): |
| 1622 | + right_tx = _get_transaction(right) |
| 1623 | + right_tx.set(timestamp=timestamp, value=value, prefix=key) |
| 1624 | + |
| 1625 | + left = self.apply(left_func, metadata=True) |
| 1626 | + right = right.update(right_func, metadata=True).filter(lambda value: False) |
| 1627 | + return left.concat(right) |
| 1628 | + |
1607 | 1629 | def ensure_topics_copartitioned(self):
|
1608 | 1630 | partitions_counts = set(t.broker_config.num_partitions for t in self._topics)
|
1609 | 1631 | if len(partitions_counts) > 1:
|
|
0 commit comments