|
50 | 50 | from quixstreams.sinks import BaseSink
|
51 | 51 | from quixstreams.state.base import State
|
52 | 52 | from quixstreams.state.base.transaction import PartitionTransaction
|
| 53 | +from quixstreams.state.rocksdb.timestamped import TimestampedStore |
53 | 54 | from quixstreams.utils.printing import (
|
54 | 55 | DEFAULT_COLUMN_NAME,
|
55 | 56 | DEFAULT_LIVE,
|
@@ -1645,6 +1646,27 @@ def concat(self, other: "StreamingDataFrame") -> "StreamingDataFrame":
|
1645 | 1646 | *self.topics, *other.topics, stream=merged_stream
|
1646 | 1647 | )
|
1647 | 1648 |
|
| 1649 | + def join(self, right: "StreamingDataFrame") -> "StreamingDataFrame": |
| 1650 | + # TODO: ensure copartitioning of left and right? |
| 1651 | + right.processing_context.state_manager.register_store( |
| 1652 | + stream_id=right.stream_id, |
| 1653 | + store_type=TimestampedStore, |
| 1654 | + changelog_config=self._topic_manager.derive_topic_config(right.topics), |
| 1655 | + ) |
| 1656 | + |
| 1657 | + def left_func(value, key, timestamp, headers): |
| 1658 | + right_tx = _get_transaction(right) |
| 1659 | + right_value = right_tx.get_last(timestamp=timestamp, prefix=key) |
| 1660 | + return {**value, **(right_value or {})} |
| 1661 | + |
| 1662 | + def right_func(value, key, timestamp, headers): |
| 1663 | + right_tx = _get_transaction(right) |
| 1664 | + right_tx.set(timestamp=timestamp, value=value, prefix=key) |
| 1665 | + |
| 1666 | + left = self.apply(left_func, metadata=True) |
| 1667 | + right = right.update(right_func, metadata=True).filter(lambda value: False) |
| 1668 | + return left.concat(right) |
| 1669 | + |
1648 | 1670 | def ensure_topics_copartitioned(self):
|
1649 | 1671 | partitions_counts = set(t.broker_config.num_partitions for t in self._topics)
|
1650 | 1672 | if len(partitions_counts) > 1:
|
|
0 commit comments