本文目录导读:

我来详细解释Python中事件溯源模式的实现。
基础架构设计
事件基类
from abc import ABC, abstractmethod
from datetime import datetime
from typing import Dict, Any, List, Optional
import uuid
import json
class Event(ABC):
"""事件基类"""
def __init__(self, aggregate_id: str):
self.event_id = str(uuid.uuid4())
self.aggregate_id = aggregate_id
self.timestamp = datetime.utcnow()
self.version = 0
@abstractmethod
def to_dict(self) -> Dict[str, Any]:
pass
@classmethod
@abstractmethod
def from_dict(cls, data: Dict[str, Any]):
pass
class AccountCreated(Event):
def __init__(self, aggregate_id: str, owner: str, initial_balance: float):
super().__init__(aggregate_id)
self.owner = owner
self.initial_balance = initial_balance
def to_dict(self):
return {
'event_type': 'AccountCreated',
'event_id': self.event_id,
'aggregate_id': self.aggregate_id,
'timestamp': self.timestamp.isoformat(),
'version': self.version,
'data': {
'owner': self.owner,
'initial_balance': self.initial_balance
}
}
@classmethod
def from_dict(cls, data):
event = cls(
data['aggregate_id'],
data['data']['owner'],
data['data']['initial_balance']
)
event.event_id = data['event_id']
event.timestamp = datetime.fromisoformat(data['timestamp'])
event.version = data['version']
return event
class MoneyDeposited(Event):
def __init__(self, aggregate_id: str, amount: float):
super().__init__(aggregate_id)
self.amount = amount
def to_dict(self):
return {
'event_type': 'MoneyDeposited',
'event_id': self.event_id,
'aggregate_id': self.aggregate_id,
'timestamp': self.timestamp.isoformat(),
'version': self.version,
'data': {
'amount': self.amount
}
}
@classmethod
def from_dict(cls, data):
event = cls(data['aggregate_id'], data['data']['amount'])
event.event_id = data['event_id']
event.timestamp = datetime.fromisoformat(data['timestamp'])
event.version = data['version']
return event
class MoneyWithdrawn(Event):
def __init__(self, aggregate_id: str, amount: float):
super().__init__(aggregate_id)
self.amount = amount
def to_dict(self):
return {
'event_type': 'MoneyWithdrawn',
'event_id': self.event_id,
'aggregate_id': self.aggregate_id,
'timestamp': self.timestamp.isoformat(),
'version': self.version,
'data': {
'amount': self.amount
}
}
@classmethod
def from_dict(cls, data):
event = cls(data['aggregate_id'], data['data']['amount'])
event.event_id = data['event_id']
event.timestamp = datetime.fromisoformat(data['timestamp'])
event.version = data['version']
return event
聚合根实现
class BankAccount:
"""银行账户聚合根"""
def __init__(self, aggregate_id: str = None):
self.aggregate_id = aggregate_id or str(uuid.uuid4())
self.owner = ""
self.balance = 0.0
self.version = 0
self.changes: List[Event] = []
def apply_event(self, event: Event):
"""应用事件到聚合根状态"""
event.version = self.version + 1
if isinstance(event, AccountCreated):
self._apply_account_created(event)
elif isinstance(event, MoneyDeposited):
self._apply_money_deposited(event)
elif isinstance(event, MoneyWithdrawn):
self._apply_money_withdrawn(event)
self.version = event.version
def _apply_account_created(self, event: AccountCreated):
self.owner = event.owner
self.balance = event.initial_balance
def _apply_money_deposited(self, event: MoneyDeposited):
self.balance += event.amount
def _apply_money_withdrawn(self, event: MoneyWithdrawn):
self.balance -= event.amount
# 业务方法
def create_account(self, owner: str, initial_balance: float):
if initial_balance < 0:
raise ValueError("Initial balance cannot be negative")
event = AccountCreated(self.aggregate_id, owner, initial_balance)
self.apply_event(event)
self.changes.append(event)
def deposit(self, amount: float):
if amount <= 0:
raise ValueError("Deposit amount must be positive")
event = MoneyDeposited(self.aggregate_id, amount)
self.apply_event(event)
self.changes.append(event)
def withdraw(self, amount: float):
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
if amount > self.balance:
raise ValueError("Insufficient funds")
event = MoneyWithdrawn(self.aggregate_id, amount)
self.apply_event(event)
self.changes.append(event)
def get_uncommitted_changes(self) -> List[Event]:
return self.changes
def mark_changes_as_committed(self):
self.changes = []
@classmethod
def from_events(cls, events: List[Event]):
"""从事件历史重建聚合根状态"""
account = cls()
for event in events:
account.apply_event(event)
account.mark_changes_as_committed()
return account
事件存储实现
from typing import Dict, List, Optional
import json
from datetime import datetime
class EventStore:
"""事件存储接口"""
def save_events(self, aggregate_id: str, events: List[Event], expected_version: int):
"""保存事件,带乐观锁控制"""
pass
def get_events(self, aggregate_id: str) -> List[Event]:
"""获取聚合的所有事件"""
pass
def get_all_events(self) -> List[Event]:
"""获取所有事件"""
pass
class InMemoryEventStore(EventStore):
"""内存事件存储实现"""
def __init__(self):
self.events: Dict[str, List[Dict]] = {}
self.event_registry = {
'AccountCreated': AccountCreated,
'MoneyDeposited': MoneyDeposited,
'MoneyWithdrawn': MoneyWithdrawn
}
def save_events(self, aggregate_id: str, events: List[Event], expected_version: int):
if aggregate_id not in self.events:
self.events[aggregate_id] = []
# 验证版本号
current_version = len(self.events[aggregate_id])
if current_version != expected_version:
raise ConcurrencyException(
f"Version conflict: expected {expected_version}, current {current_version}"
)
# 保存事件
for event in events:
self.events[aggregate_id].append(event.to_dict())
def get_events(self, aggregate_id: str) -> List[Event]:
if aggregate_id not in self.events:
return []
events = []
for event_data in self.events[aggregate_id]:
event_type = event_data['event_type']
event_class = self.event_registry[event_type]
events.append(event_class.from_dict(event_data))
return events
def get_all_events(self) -> List[Event]:
all_events = []
for aggregate_events in self.events.values():
for event_data in aggregate_events:
event_type = event_data['event_type']
event_class = self.event_registry[event_type]
all_events.append(event_class.from_dict(event_data))
# 按时间戳排序
all_events.sort(key=lambda e: e.timestamp)
return all_events
class ConcurrencyException(Exception):
"""并发异常"""
pass
仓储模式实现
class AccountRepository:
"""账户仓储"""
def __init__(self, event_store: EventStore):
self.event_store = event_store
def save(self, account: BankAccount):
"""保存账户的未提交更改"""
changes = account.get_uncommitted_changes()
if not changes:
return
# 期望版本 = 当前聚合版本 - 未提交事件数量
expected_version = account.version - len(changes)
self.event_store.save_events(
account.aggregate_id,
changes,
expected_version
)
account.mark_changes_as_committed()
def get_by_id(self, aggregate_id: str) -> Optional[BankAccount]:
"""通过ID获取账户"""
events = self.event_store.get_events(aggregate_id)
if not events:
return None
return BankAccount.from_events(events)
投影和查询实现
class AccountProjection:
"""账户投影 - 用于查询优化"""
def __init__(self):
self.accounts: Dict[str, Dict] = {}
def project(self, event: Event):
"""处理事件更新投影"""
if isinstance(event, AccountCreated):
self.accounts[event.aggregate_id] = {
'id': event.aggregate_id,
'owner': event.owner,
'balance': event.initial_balance,
'created_at': event.timestamp
}
elif isinstance(event, MoneyDeposited):
if event.aggregate_id in self.accounts:
self.accounts[event.aggregate_id]['balance'] += event.amount
elif isinstance(event, MoneyWithdrawn):
if event.aggregate_id in self.accounts:
self.accounts[event.aggregate_id]['balance'] -= event.amount
def get_account(self, aggregate_id: str) -> Optional[Dict]:
return self.accounts.get(aggregate_id)
def get_all_accounts(self) -> List[Dict]:
return list(self.accounts.values())
def rebuild_from_events(self, events: List[Event]):
"""从事件历史重建投影"""
self.accounts = {}
for event in events:
self.project(event)
class AccountQueryService:
"""账户查询服务"""
def __init__(self, projection: AccountProjection):
self.projection = projection
def get_balance(self, account_id: str) -> Optional[float]:
account = self.projection.get_account(account_id)
if account:
return account['balance']
return None
def get_account_summary(self, account_id: str) -> Optional[Dict]:
return self.projection.get_account(account_id)
使用示例
def main():
# 初始化组件
event_store = InMemoryEventStore()
repository = AccountRepository(event_store)
projection = AccountProjection()
query_service = AccountQueryService(projection)
# 1. 创建账户
print("=== 创建账户 ===")
account = BankAccount()
account.create_account("John Doe", 1000.0)
repository.save(account)
print(f"Created account {account.aggregate_id} with balance {account.balance}")
# 2. 存款
print("\n=== 存款操作 ===")
account.deposit(500.0)
repository.save(account)
print(f"Deposited 500. Balance: {account.balance}")
# 3. 取款
print("\n=== 取款操作 ===")
account.withdraw(200.0)
repository.save(account)
print(f"Withdrew 200. Balance: {account.balance}")
# 4. 更新投影
print("\n=== 更新投影 ===")
all_events = event_store.get_all_events()
projection.rebuild_from_events(all_events)
# 5. 查询操作
print("\n=== 查询操作 ===")
summary = query_service.get_account_summary(account.aggregate_id)
print(f"Account Summary: {summary}")
balance = query_service.get_balance(account.aggregate_id)
print(f"Current Balance: {balance}")
# 6. 从事件历史重建聚合
print("\n=== 从事件历史重建 ===")
loaded_account = repository.get_by_id(account.aggregate_id)
print(f"Loaded account: {loaded_account.aggregate_id}")
print(f"Owner: {loaded_account.owner}")
print(f"Balance: {loaded_account.balance}")
print(f"Version: {loaded_account.version}")
if __name__ == "__main__":
main()
高级特性实现
事件版本控制
class EventVersion:
def __init__(self):
self.version = 0
self.upgraders = {}
def register_upgrader(self, from_version: int, to_version: int, upgrader):
"""注册事件升级器"""
self.upgraders[(from_version, to_version)] = upgrader
def upgrade_events(self, events: List[Event]) -> List[Event]:
"""升级事件到最新版本"""
upgraded_events = []
for event in events:
current_version = event.version
while current_version < self.version:
next_version = current_version + 1
if (current_version, next_version) in self.upgraders:
event = self.upgraders[(current_version, next_version)](event)
current_version = next_version
upgraded_events.append(event)
return upgraded_events
快照管理
class Snapshot:
def __init__(self, aggregate_id: str, version: int, state: Dict):
self.aggregate_id = aggregate_id
self.version = version
self.state = state
self.created_at = datetime.utcnow()
class SnapshotRepository:
def __init__(self, snapshot_threshold: int = 100):
self.snapshots: Dict[str, Snapshot] = {}
self.threshold = snapshot_threshold
def save_snapshot(self, account: BankAccount):
"""保存快照"""
if account.version >= self.threshold and account.version % self.threshold == 0:
snapshot = Snapshot(
account.aggregate_id,
account.version,
{
'owner': account.owner,
'balance': account.balance
}
)
self.snapshots[account.aggregate_id] = snapshot
def get_snapshot(self, aggregate_id: str) -> Optional[Snapshot]:
"""获取快照"""
return self.snapshots.get(aggregate_id)
这个实现包含了事件溯源的核心概念,可以根据具体需求进行扩展和优化。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播