Vermeidung von duckdb OutOfRangeException beim Multiplizieren von DezimalzahlenPython

Python-Programme
Anonymous
 Vermeidung von duckdb OutOfRangeException beim Multiplizieren von Dezimalzahlen

Post by Anonymous »

Ich arbeite mit DuckDB und habe mehrere vom Client bereitgestellte SQL-Ausdrücke, die DECIMAL(38,10)-Spalten verwenden (feste Genauigkeit mit 10 Nachkommastellen).
Zum Beispiel:

Code: Select all

SELECT S1__AMOUNT * S1__PRICE * S1__UNITS * 1000
Alle Spalten wie S1__AMOUNT, S1__PRICE usw. sind DEZIMAL (38,10).
Wenn ich mehrere dieser Spalten (insbesondere drei oder mehr) multipliziere und dann mit einer Konstante (z. B. * 1000) multipliziere, erhalte ich:

Code: Select all

duckdb.duckdb.OutOfRangeException: Out of Range Error:
Overflow in multiplication of DECIMAL(38) (194586756000000000000000000000000000 * 1000).
You might want to add an explicit cast to a decimal with a smaller scale.
Einschränkungen:
Ich kann nicht in DOUBLE umwandeln, aber nach jeder Operation darf das Ergebnis in eine Dezimalzahl (38,10) umgewandelt werden
Ich weiß, dass ich die SQL-Klausel manuell umschreiben kann, um sie nach jedem Schritt umzuwandeln, wie zum Beispiel:

Code: Select all

CAST(
CAST(
CAST(S1__AMOUNT * S1__PRICE AS DECIMAL(38,10))
* S1__UNITS AS DECIMAL(38,10)
)
* 1000 AS DECIMAL(38,10)
)
Aber da SQL-Klauseln vom Client geschrieben werden und ziemlich zufällig sein können, möchte ich diese umständliche und fehleranfällige Methode nicht verwenden.
Die Frage:
Gibt es eine Möglichkeit, DuckDB so zu konfigurieren, dass es:
  • Zwischendezimalskala/-genauigkeit bei Bedarf automatisch reduziert, um in DECIMAL(38,10) zu passen, ohne eine OutOfRangeException auszulösen, oder
  • Zwischenarithmetische Ergebnisse automatisch zurück in ein sicheres DECIMAL(38,10) umwandeln oder
  • Stellt einen Ausdruck/eine Funktion zum sicheren „Multiplizieren mit überlaufsicherer Dezimalheraufstufung“ bereit?
Wenn nicht, ist dies der einzig zuverlässige Ansatz, alle Ausdrücke neu zu schreiben und nach jedem explizite Umwandlungen einzufügen Multiplikation/Division?
Genauer Code zur Reproduktion des Problems:

Code: Select all

import duckdb
import polars as pl

df = pl.DataFrame({"AMOUNT": 8760, "PRICE": 22.2131, "RATE": 1})
df = df.cast(pl.Decimal(scale=10))

result = duckdb.sql("""
FROM df
SELECT AMOUNT * PRICE * RATE * 1000
""").pl()

print(result)

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post