@@ -5,6 +5,136 @@ Changelog
55
66=========
77
8+ 4.1.0 (2025-11-28)
9+ ------------------
10+
11+ Features
12+ ~~~~~~~~
13+
14+ Decimal Data Type Support
15+ *************************
16+
17+ This release adds support for ingesting data into QuestDB's native
18+ ``DECIMAL(precision, scale) `` column type introduced in QuestDB 9.2.0.
19+ Use decimals when you need exact-precision values (e.g. prices, balances)
20+ without floating-point rounding issues.
21+
22+ Decimal values can be sent using Python ``decimal.Decimal `` objects in both
23+ ``row() `` and ``dataframe() `` methods. When sending dataframes, you can also use
24+ PyArrow decimal types for better performance.
25+
26+ Sending decimals requires protocol version 3. When using HTTP, this protocol
27+ version is auto-negotiated. For TCP connections, you must explicitly specify
28+ ``protocol_version=3 `` in the configuration string:
29+
30+ .. code-block :: python
31+
32+ # HTTP - protocol version 3 is auto-negotiated
33+ conf = ' http::addr=localhost:9000;'
34+
35+ # TCP - must specify protocol_version=3 explicitly
36+ conf = ' tcp::addr=localhost:9009;protocol_version=3;'
37+
38+ .. important ::
39+ **Server Requirement **: This feature requires QuestDB server version 9.2.0 or higher.
40+
41+ Unlike other column types, DECIMAL columns **must be created in advance ** via SQL
42+ before ingesting data. Auto-creation is not supported for DECIMAL columns.
43+
44+ For details on creating DECIMAL columns and working with this data type, see the
45+ `QuestDB Decimal documentation <https://questdb.com/docs/concept/decimal/ >`_.
46+
47+ **Usage with Python Decimal objects: **
48+
49+ .. code-block :: python
50+
51+ from decimal import Decimal
52+ from questdb.ingress import Sender, TimestampNanos
53+
54+ # First, create the table with DECIMAL column via SQL:
55+ # CREATE TABLE trades (
56+ # symbol SYMBOL,
57+ # price DECIMAL(18,4),
58+ # amount DECIMAL(18,8),
59+ # timestamp TIMESTAMP
60+ # ) TIMESTAMP(timestamp);
61+
62+ conf = ' http::addr=localhost:9000;'
63+ with Sender.from_conf(conf) as sender:
64+ sender.row(
65+ ' trades' ,
66+ symbols = {' symbol' : ' ETH-USD' },
67+ columns = {
68+ ' price' : Decimal(' 2615.5400' ),
69+ ' amount' : Decimal(' 0.00044000' )},
70+ at = TimestampNanos.now())
71+
72+ **Usage with Python Decimal objects in Pandas dataframes: **
73+
74+ .. code-block :: python
75+
76+ import pandas as pd
77+ from decimal import Decimal
78+
79+ # Create DataFrame with Python Decimal objects
80+ df = pd.DataFrame({
81+ ' symbol' : [' ETH-USD' , ' BTC-USD' ],
82+ ' price' : [Decimal(' 2615.5400' ), Decimal(' 43210.1234' )],
83+ ' volume' : [Decimal(' 1234.56789012' ), Decimal(' 98.76543210' )]
84+ })
85+
86+ with Sender.from_conf(conf) as sender:
87+ sender.dataframe(
88+ df,
89+ table_name = ' trades' ,
90+ symbols = ' symbol' ,
91+ at = TimestampNanos.now())
92+
93+ **Usage with PyArrow Decimal types in Pandas dataframes: **
94+
95+ .. code-block :: python
96+
97+ import pandas as pd
98+ import pyarrow as pa
99+ from decimal import Decimal
100+
101+ # Create DataFrame with Arrow decimal types
102+ df = pd.DataFrame({
103+ ' prices' : pd.array(
104+ [Decimal(' -99999.99' ), Decimal(' -678.00' )],
105+ dtype = pd.ArrowDtype(pa.decimal128(18 , 2 ))
106+ )
107+ })
108+
109+ with Sender.from_conf(conf) as sender:
110+ sender.dataframe(df, table_name = ' prices' , at = TimestampNanos.now())
111+
112+ Additional Arrow Data Type Support
113+ **********************************
114+
115+ Added support for additional PyArrow column types commonly encountered when
116+ deserializing from Parquet files or converting Polars dataframes to Pandas:
117+
118+ * ``int16 ``, ``int32 ``, ``float32 `` (float), ``bool ``
119+ * ``string ``, ``large_string `` (including as symbol types)
120+ * ``timestamp[us] `` with timezone support for microsecond-precision timestamps
121+
122+ Microsecond Timestamp Precision
123+ *******************************
124+
125+ Microsecond-precision timestamp columns (``datetime64[us] `` in NumPy and
126+ ``timestamp[us] `` in PyArrow) are now fully supported. When using
127+ ``protocol_version `` 2 or higher, microsecond timestamps are sent with full
128+ precision, including for the designated timestamp column.
129+
130+ Bug fixes
131+ ~~~~~~~~~
132+
133+ * Updated type hints to allow ``None `` as a valid column value in
134+ ``Sender.row() ``. This brings the type annotations in line with the actual
135+ behavior, where ``None `` values have always been supported to represent NULL
136+ values.
137+
81384.0.0 (2025-10-17)
9139------------------
10140
0 commit comments