Add initial version of key value store
This commit is contained in:
parent
f8d89c46e5
commit
c083723698
@ -1,5 +1,6 @@
|
|||||||
# flake8: noqa: F401
|
# flake8: noqa: F401
|
||||||
|
|
||||||
|
from freqtrade.persistence.key_value_store import KeyValueStore
|
||||||
from freqtrade.persistence.models import init_db
|
from freqtrade.persistence.models import init_db
|
||||||
from freqtrade.persistence.pairlock_middleware import PairLocks
|
from freqtrade.persistence.pairlock_middleware import PairLocks
|
||||||
from freqtrade.persistence.trade_model import LocalTrade, Order, Trade
|
from freqtrade.persistence.trade_model import LocalTrade, Order, Trade
|
||||||
|
97
freqtrade/persistence/key_value_store.py
Normal file
97
freqtrade/persistence/key_value_store.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
from datetime import datetime, timezone
|
||||||
|
from enum import Enum
|
||||||
|
from typing import ClassVar, Optional, Union
|
||||||
|
|
||||||
|
from sqlalchemy import String
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from freqtrade.persistence.base import ModelBase, SessionType
|
||||||
|
|
||||||
|
|
||||||
|
ValueTypes = Union[str, datetime, float, int]
|
||||||
|
|
||||||
|
|
||||||
|
class ValueTypesEnum(str, Enum):
|
||||||
|
STRING = 'str'
|
||||||
|
DATETIME = 'datetime'
|
||||||
|
FLOAT = 'float'
|
||||||
|
INT = 'int'
|
||||||
|
|
||||||
|
|
||||||
|
class _KeyValueStoreModel(ModelBase):
|
||||||
|
"""
|
||||||
|
Pair Locks database model.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'KeyValueStore'
|
||||||
|
session: ClassVar[SessionType]
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
|
||||||
|
key: Mapped[str] = mapped_column(String(25), nullable=False, index=True)
|
||||||
|
|
||||||
|
value_type: Mapped[ValueTypesEnum] = mapped_column(String(25), nullable=False)
|
||||||
|
|
||||||
|
string_value: Mapped[Optional[str]]
|
||||||
|
datetime_value: Mapped[Optional[datetime]]
|
||||||
|
float_value: Mapped[Optional[float]]
|
||||||
|
int_value: Mapped[Optional[int]]
|
||||||
|
|
||||||
|
|
||||||
|
class KeyValueStore():
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_value(key: str) -> Optional[ValueTypes]:
|
||||||
|
"""
|
||||||
|
Get the value for the given key.
|
||||||
|
"""
|
||||||
|
kv = _KeyValueStoreModel.session.query(_KeyValueStoreModel).filter(
|
||||||
|
_KeyValueStoreModel.key == key).first()
|
||||||
|
if kv is None:
|
||||||
|
return None
|
||||||
|
if kv.value_type == ValueTypesEnum.STRING:
|
||||||
|
return kv.string_value
|
||||||
|
if kv.value_type == ValueTypesEnum.DATETIME and kv.datetime_value is not None:
|
||||||
|
return kv.datetime_value.replace(tzinfo=timezone.utc)
|
||||||
|
if kv.value_type == ValueTypesEnum.FLOAT:
|
||||||
|
return kv.float_value
|
||||||
|
if kv.value_type == ValueTypesEnum.INT:
|
||||||
|
return kv.int_value
|
||||||
|
# This should never happen unless someone messed with the database manually
|
||||||
|
raise ValueError(f'Unknown value type {kv.value_type}') # pragma: no cover
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def store_value(key: str, value: ValueTypes) -> None:
|
||||||
|
"""
|
||||||
|
Store the given value for the given key.
|
||||||
|
"""
|
||||||
|
kv = _KeyValueStoreModel.session.query(_KeyValueStoreModel).filter(
|
||||||
|
_KeyValueStoreModel.key == key).first()
|
||||||
|
if kv is None:
|
||||||
|
kv = _KeyValueStoreModel(key=key)
|
||||||
|
if isinstance(value, str):
|
||||||
|
kv.value_type = ValueTypesEnum.STRING
|
||||||
|
kv.string_value = value
|
||||||
|
elif isinstance(value, datetime):
|
||||||
|
kv.value_type = ValueTypesEnum.DATETIME
|
||||||
|
kv.datetime_value = value
|
||||||
|
elif isinstance(value, float):
|
||||||
|
kv.value_type = ValueTypesEnum.FLOAT
|
||||||
|
kv.float_value = value
|
||||||
|
elif isinstance(value, int):
|
||||||
|
kv.value_type = ValueTypesEnum.INT
|
||||||
|
kv.int_value = value
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown value type {kv.value_type}')
|
||||||
|
_KeyValueStoreModel.session.add(kv)
|
||||||
|
_KeyValueStoreModel.session.commit()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def delete_value(key: str) -> None:
|
||||||
|
"""
|
||||||
|
Delete the value for the given key.
|
||||||
|
"""
|
||||||
|
kv = _KeyValueStoreModel.session.query(_KeyValueStoreModel).filter(
|
||||||
|
_KeyValueStoreModel.key == key).first()
|
||||||
|
if kv is not None:
|
||||||
|
_KeyValueStoreModel.session.delete(kv)
|
||||||
|
_KeyValueStoreModel.session.commit()
|
@ -13,6 +13,7 @@ from sqlalchemy.pool import StaticPool
|
|||||||
|
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.persistence.base import ModelBase
|
from freqtrade.persistence.base import ModelBase
|
||||||
|
from freqtrade.persistence.key_value_store import _KeyValueStoreModel
|
||||||
from freqtrade.persistence.migrations import check_migrate
|
from freqtrade.persistence.migrations import check_migrate
|
||||||
from freqtrade.persistence.pairlock import PairLock
|
from freqtrade.persistence.pairlock import PairLock
|
||||||
from freqtrade.persistence.trade_model import Order, Trade
|
from freqtrade.persistence.trade_model import Order, Trade
|
||||||
@ -76,6 +77,7 @@ def init_db(db_url: str) -> None:
|
|||||||
bind=engine, autoflush=False), scopefunc=get_request_or_thread_id)
|
bind=engine, autoflush=False), scopefunc=get_request_or_thread_id)
|
||||||
Order.session = Trade.session
|
Order.session = Trade.session
|
||||||
PairLock.session = Trade.session
|
PairLock.session = Trade.session
|
||||||
|
_KeyValueStoreModel.session = Trade.session
|
||||||
|
|
||||||
previous_tables = inspect(engine).get_table_names()
|
previous_tables = inspect(engine).get_table_names()
|
||||||
ModelBase.metadata.create_all(engine)
|
ModelBase.metadata.create_all(engine)
|
||||||
|
Loading…
Reference in New Issue
Block a user