TCPDashboard/database/repositories/raw_trade_repository.py
Vasily.onl 1466223b85 Refactor raw trade management and enhance database operations
- Removed the `RawDataManager` class and integrated its functionality directly into the `RawTradeRepository`, streamlining the management of raw trade data.
- Implemented the `cleanup_old_raw_data` method to delete outdated records, preventing table bloat and improving performance.
- Added the `get_raw_data_stats` method to retrieve statistics about raw data storage, enhancing data management capabilities.
- Updated documentation to reflect the new methods and their usage, ensuring clarity for future developers.

These changes improve the maintainability and efficiency of the database operations related to raw trade data.
2025-06-06 23:51:21 +08:00

160 lines
6.3 KiB
Python

"""Repository for raw_trades table operations."""
from datetime import datetime, timedelta
from typing import Dict, Any, Optional, List
from sqlalchemy import desc, text
from ..models import RawTrade
from data.base_collector import MarketDataPoint
from .base_repository import BaseRepository, DatabaseOperationError
class RawTradeRepository(BaseRepository):
"""Repository for raw_trades table operations."""
def insert_market_data_point(self, data_point: MarketDataPoint) -> bool:
"""
Insert a market data point into raw_trades table using the ORM.
"""
try:
with self.get_session() as session:
new_trade = RawTrade(
exchange=data_point.exchange,
symbol=data_point.symbol,
timestamp=data_point.timestamp,
data_type=data_point.data_type.value,
raw_data=data_point.data
)
session.add(new_trade)
session.commit()
self.log_debug(f"Stored raw {data_point.data_type.value} data for {data_point.symbol}")
return True
except Exception as e:
self.log_error(f"Error storing raw data for {data_point.symbol}: {e}")
raise DatabaseOperationError(f"Failed to store raw data: {e}")
def insert_raw_websocket_data(self,
exchange: str,
symbol: str,
data_type: str,
raw_data: Dict[str, Any],
timestamp: Optional[datetime] = None) -> bool:
"""
Insert raw WebSocket data for debugging purposes using the ORM.
"""
try:
with self.get_session() as session:
new_trade = RawTrade(
exchange=exchange,
symbol=symbol,
timestamp=timestamp or datetime.now(datetime.timezone.utc),
data_type=data_type,
raw_data=raw_data
)
session.add(new_trade)
session.commit()
self.log_debug(f"Stored raw WebSocket data: {data_type} for {symbol}")
return True
except Exception as e:
self.log_error(f"Error storing raw WebSocket data for {symbol}: {e}")
raise DatabaseOperationError(f"Failed to store raw WebSocket data: {e}")
def get_raw_trades(self,
symbol: str,
data_type: str,
start_time: datetime,
end_time: datetime,
exchange: str = "okx",
limit: Optional[int] = None) -> List[Dict[str, Any]]:
"""
Retrieve raw trades from the database using the ORM.
"""
try:
with self.get_session() as session:
query = (
session.query(RawTrade)
.filter(
RawTrade.exchange == exchange,
RawTrade.symbol == symbol,
RawTrade.data_type == data_type,
RawTrade.timestamp >= start_time,
RawTrade.timestamp <= end_time
)
.order_by(RawTrade.timestamp.asc())
)
if limit:
query = query.limit(limit)
results = query.all()
trades = [
{
"id": r.id, "exchange": r.exchange, "symbol": r.symbol,
"timestamp": r.timestamp, "data_type": r.data_type,
"raw_data": r.raw_data, "created_at": r.created_at
} for r in results
]
self.log_info(f"Retrieved {len(trades)} raw trades for {symbol} {data_type}")
return trades
except Exception as e:
self.log_error(f"Error retrieving raw trades for {symbol}: {e}")
raise DatabaseOperationError(f"Failed to retrieve raw trades: {e}")
def cleanup_old_raw_data(self, days_to_keep: int = 7) -> int:
"""
Clean up old raw data to prevent table bloat.
Args:
days_to_keep: Number of days to retain data.
Returns:
Number of records deleted.
"""
try:
cutoff_date = datetime.now(datetime.timezone.utc) - timedelta(days=days_to_keep)
with self.get_session() as session:
result = session.execute(
text("DELETE FROM raw_trades WHERE created_at < :cutoff_date"),
{"cutoff_date": cutoff_date}
)
deleted_count = result.rowcount
session.commit()
self.log_info(f"Cleaned up {deleted_count} old raw data records")
return deleted_count
except Exception as e:
self.log_error(f"Failed to cleanup raw data: {e}")
raise DatabaseOperationError(f"Failed to cleanup raw data: {e}")
def get_raw_data_stats(self) -> Dict[str, Any]:
"""Get statistics about raw data storage."""
try:
with self.get_session() as session:
result = session.execute(text("""
SELECT
COUNT(*) as total_records,
COUNT(DISTINCT symbol) as unique_symbols,
COUNT(DISTINCT data_type) as data_types,
MIN(created_at) as oldest_record,
MAX(created_at) as newest_record,
pg_size_pretty(pg_total_relation_size('raw_trades')) as table_size
FROM raw_trades
""")).fetchone()
if result:
return dict(result._mapping)
return {"status": "No data available"}
except Exception as e:
self.log_error(f"Failed to get raw data stats: {e}")
raise DatabaseOperationError(f"Failed to get raw data stats: {e}")