Check that price numbers aren't too big for GnuCash.
This commit is contained in:
parent
303f5d379a
commit
82c4f45ce0
1 changed files with 20 additions and 3 deletions
|
@ -27,6 +27,7 @@ class GnuCashSQL(BaseOutput):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
too_big = False
|
||||||
values_parts = []
|
values_parts = []
|
||||||
for price in series.prices:
|
for price in series.prices:
|
||||||
date = f"{fmt.format_date(price.date)} {fmt.time}"
|
date = f"{fmt.format_date(price.date)} {fmt.time}"
|
||||||
|
@ -45,7 +46,8 @@ class GnuCashSQL(BaseOutput):
|
||||||
)
|
)
|
||||||
guid = m.hexdigest()[0:32]
|
guid = m.hexdigest()[0:32]
|
||||||
|
|
||||||
value_num, value_denom = self._rational(price.amount)
|
value_num, value_denom, fit = self._rational(price.amount)
|
||||||
|
too_big |= not fit
|
||||||
v = (
|
v = (
|
||||||
"("
|
"("
|
||||||
+ ", ".join(
|
+ ", ".join(
|
||||||
|
@ -65,6 +67,17 @@ class GnuCashSQL(BaseOutput):
|
||||||
values_parts.append(v)
|
values_parts.append(v)
|
||||||
values = ",\n".join(values_parts)
|
values = ",\n".join(values_parts)
|
||||||
|
|
||||||
|
if too_big:
|
||||||
|
# https://code.gnucash.org/docs/MAINT/group__Numeric.html
|
||||||
|
# https://code.gnucash.org/docs/MAINT/structgnc__price__s.html
|
||||||
|
logging.warn(
|
||||||
|
"This SQL contains numbers outside of the int64 range required "
|
||||||
|
"by GnuCash for the numerators and denominators of prices. "
|
||||||
|
"Using the --quantize option to limit the number of decimal "
|
||||||
|
"places will usually reduce the size of the rational form as "
|
||||||
|
"well."
|
||||||
|
)
|
||||||
|
|
||||||
sql = read_text("pricehist.resources", "gnucash.sql").format(
|
sql = read_text("pricehist.resources", "gnucash.sql").format(
|
||||||
version=__version__,
|
version=__version__,
|
||||||
timestamp=datetime.utcnow().isoformat() + "Z",
|
timestamp=datetime.utcnow().isoformat() + "Z",
|
||||||
|
@ -104,7 +117,7 @@ class GnuCashSQL(BaseOutput):
|
||||||
quoted = f"'{escaped}'"
|
quoted = f"'{escaped}'"
|
||||||
return quoted
|
return quoted
|
||||||
|
|
||||||
def _rational(self, number: Decimal) -> (str, str):
|
def _rational(self, number: Decimal) -> (str, str, bool):
|
||||||
tup = number.as_tuple()
|
tup = number.as_tuple()
|
||||||
sign = "-" if tup.sign == 1 else ""
|
sign = "-" if tup.sign == 1 else ""
|
||||||
if tup.exponent > 0:
|
if tup.exponent > 0:
|
||||||
|
@ -115,4 +128,8 @@ class GnuCashSQL(BaseOutput):
|
||||||
else:
|
else:
|
||||||
numerator = sign + "".join([str(d) for d in tup.digits])
|
numerator = sign + "".join([str(d) for d in tup.digits])
|
||||||
denom = str(10 ** -tup.exponent)
|
denom = str(10 ** -tup.exponent)
|
||||||
return (numerator, denom)
|
fit = self._fit_in_int64(Decimal(numerator), Decimal(denom))
|
||||||
|
return (numerator, denom, fit)
|
||||||
|
|
||||||
|
def _fit_in_int64(self, *numbers):
|
||||||
|
return all(n >= -(2 ** 63) and n <= (2 ** 63) - 1 for n in numbers)
|
||||||
|
|
Loading…
Add table
Reference in a new issue