Files
2026-07-13 12:07:23 +08:00

160 lines
3.5 KiB
Python

from abc import ABC, abstractmethod
from datetime import datetime
from types import ModuleType
from dataclasses import dataclass
from importlib import import_module
from .constant import Interval, Exchange
from .object import BarData, TickData
from .setting import SETTINGS
from .utility import ZoneInfo
from .locale import _
DB_TZ = ZoneInfo(SETTINGS["database.timezone"])
def convert_tz(dt: datetime) -> datetime:
"""
Convert timezone of datetime object to DB_TZ.
"""
dt = dt.astimezone(DB_TZ)
return dt.replace(tzinfo=None)
@dataclass
class BarOverview:
"""
Overview of bar data stored in database.
"""
symbol: str = ""
exchange: Exchange | None = None
interval: Interval | None = None
count: int = 0
start: datetime | None = None
end: datetime | None = None
@dataclass
class TickOverview:
"""
Overview of tick data stored in database.
"""
symbol: str = ""
exchange: Exchange | None = None
count: int = 0
start: datetime | None = None
end: datetime | None = None
class BaseDatabase(ABC):
"""
Abstract database class for connecting to different database.
"""
@abstractmethod
def save_bar_data(self, bars: list[BarData], stream: bool = False) -> bool:
"""
Save bar data into database.
"""
pass
@abstractmethod
def save_tick_data(self, ticks: list[TickData], stream: bool = False) -> bool:
"""
Save tick data into database.
"""
pass
@abstractmethod
def load_bar_data(
self,
symbol: str,
exchange: Exchange,
interval: Interval,
start: datetime,
end: datetime
) -> list[BarData]:
"""
Load bar data from database.
"""
pass
@abstractmethod
def load_tick_data(
self,
symbol: str,
exchange: Exchange,
start: datetime,
end: datetime
) -> list[TickData]:
"""
Load tick data from database.
"""
pass
@abstractmethod
def delete_bar_data(
self,
symbol: str,
exchange: Exchange,
interval: Interval
) -> int:
"""
Delete all bar data with given symbol + exchange + interval.
"""
pass
@abstractmethod
def delete_tick_data(
self,
symbol: str,
exchange: Exchange
) -> int:
"""
Delete all tick data with given symbol + exchange.
"""
pass
@abstractmethod
def get_bar_overview(self) -> list[BarOverview]:
"""
Return bar data avaible in database.
"""
pass
@abstractmethod
def get_tick_overview(self) -> list[TickOverview]:
"""
Return tick data avaible in database.
"""
pass
database: BaseDatabase | None = None
def get_database() -> BaseDatabase:
""""""
# Return database object if already inited
global database
if database:
return database
# Read database related global setting
database_name: str = SETTINGS["database.name"]
module_name: str = f"vnpy_{database_name}"
# Try to import database module
try:
module: ModuleType = import_module(module_name)
except ModuleNotFoundError:
print(_("找不到数据库驱动{},使用默认的SQLite数据库").format(module_name))
module = import_module("vnpy_sqlite")
# Create database object from module
database = module.Database()
return database