From b2b19915e6e6180cd1602fc41a73d7f4428de91a Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 12 Apr 2023 06:54:06 +0200 Subject: [PATCH] Limit enter_tag and exit_reason to their actual field lenght closes #8486 --- freqtrade/constants.py | 2 +- freqtrade/persistence/trade_model.py | 9 ++++++++- tests/persistence/test_persistence.py | 28 ++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index d83072064..2fcb957a3 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -64,7 +64,7 @@ USERPATH_FREQAIMODELS = 'freqaimodels' TELEGRAM_SETTING_OPTIONS = ['on', 'off', 'silent'] WEBHOOK_FORMAT_OPTIONS = ['form', 'json', 'raw'] FULL_DATAFRAME_THRESHOLD = 100 -CUSTOM_TAG_MAX_LENGTH = 64 +CUSTOM_TAG_MAX_LENGTH = 100 ENV_VAR_PREFIX = 'FREQTRADE__' diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index a9d58f6ec..0572b45a6 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Sequence, cast from sqlalchemy import (Enum, Float, ForeignKey, Integer, ScalarResult, Select, String, UniqueConstraint, desc, func, select) -from sqlalchemy.orm import Mapped, lazyload, mapped_column, relationship +from sqlalchemy.orm import Mapped, lazyload, mapped_column, relationship, validates from freqtrade.constants import (CUSTOM_TAG_MAX_LENGTH, DATETIME_PRINT_FORMAT, MATH_CLOSE_PREC, NON_OPEN_EXCHANGE_STATES, BuySell, LongShort) @@ -1295,6 +1295,13 @@ class Trade(ModelBase, LocalTrade): self.realized_profit = 0 self.recalc_open_trade_value() + @validates('enter_tag', 'exit_reason') + def validate_string_len(self, key, value): + max_len = getattr(self.__class__, key).prop.columns[0].type.length + if value and len(value) > max_len: + return value[:max_len] + return value + def delete(self) -> None: for order in self.orders: diff --git a/tests/persistence/test_persistence.py b/tests/persistence/test_persistence.py index 23ec6d4fb..948973ed5 100644 --- a/tests/persistence/test_persistence.py +++ b/tests/persistence/test_persistence.py @@ -6,7 +6,7 @@ import arrow import pytest from sqlalchemy import select -from freqtrade.constants import DATETIME_PRINT_FORMAT +from freqtrade.constants import CUSTOM_TAG_MAX_LENGTH, DATETIME_PRINT_FORMAT from freqtrade.enums import TradingMode from freqtrade.exceptions import DependencyException from freqtrade.persistence import LocalTrade, Order, Trade, init_db @@ -2037,6 +2037,7 @@ def test_Trade_object_idem(): 'get_mix_tag_performance', 'get_trading_volume', 'from_json', + 'validate_string_len', ) EXCLUDES2 = ('trades', 'trades_open', 'bt_trades_open_pp', 'bt_open_open_trade_count', 'total_profit') @@ -2055,6 +2056,31 @@ def test_Trade_object_idem(): assert item in trade +@pytest.mark.usefixtures("init_persistence") +def test_trade_truncates_string_fields(): + trade = Trade( + pair='ADA/USDT', + stake_amount=20.0, + amount=30.0, + open_rate=2.0, + open_date=datetime.utcnow() - timedelta(minutes=20), + fee_open=0.001, + fee_close=0.001, + exchange='binance', + leverage=1.0, + trading_mode='futures', + enter_tag='a' * CUSTOM_TAG_MAX_LENGTH * 2, + exit_reason='b' * CUSTOM_TAG_MAX_LENGTH * 2, + ) + Trade.session.add(trade) + Trade.commit() + + trade1 = Trade.session.scalars(select(Trade)).first() + + assert trade1.enter_tag == 'a' * CUSTOM_TAG_MAX_LENGTH + assert trade1.exit_reason == 'b' * CUSTOM_TAG_MAX_LENGTH + + def test_recalc_trade_from_orders(fee): o1_amount = 100