2.0.0
What's Changed
This is a major release with new features and breaking changes.
Features
-
Support for ILP over HTTP. The sender can now send data to QuestDB via HTTP instead of TCP. This provides error feedback from the server and new features.
conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: sender.row(...) sender.dataframe(...) # Will raise `IngressError` if there is an error from the server. sender.flush()
-
New configuration string construction. The sender can now be also constructed from a configuration string in addition to the constructor arguments. This allows for more flexible configuration and is the recommended way to construct a sender. The same string can also be loaded from the
QDB_CLIENT_CONFenvironment variable. The constructor arguments have been updated and some options have changed. -
Explicit transaction support over HTTP. A set of rows for a single table can now be committed via the sender transactionally. You can do this using a
with sender.transaction('table_name') as txn:block.conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: with sender.transaction('test_table') as txn: # Same arguments as the sender methods, minus the table name. txn.row(...) txn.dataframe(...)
-
A number of documentation improvements.
Breaking Changes
-
New
protocolparameter in the Sender constructor. In the previous version, the protocol was always TCP. In this new version, you must specify the protocol explicitly. -
New auto-flush defaults. In previous versions, auto-flushing was enabled by default and triggered by a maximum buffer size. In this new version, auto-flushing is enabled by row count (600 rows by default) and interval (1 second by default), while auto-flushing by buffer size is disabled by default.
The old behavior can still be achieved by tweaking the auto-flush settings.
Setting Old default New default auto_flush_rows off 600 auto_flush_interval off 1000 auto_flush_bytes 64512 off -
The
at=..argument of therowanddataframemethods is now mandatory. Omitting it would previously use a server-generated timestamp for the row. Now, if you want a server-generated timestamp, you can pass theServerTimestampsingleton to this parameter. TheServerTimestampbehavior is considered legacy. -
The
auth=(u, t, x, y)argument of theSenderconstructor has now been broken up into multiple arguments:username,token,token_x,token_y. -
The
tlsargument of theSenderconstructor has been removed and replaced with theprotocolargument. UseProtocol.Tcps(orProtocol.Https) to enable TLS. Thetlsvalues have been moved to newtls_caandtls_rootsconfiguration settings. -
The
net_interfaceargument of theSenderconstructor has been renamed tobind_interfaceand is now only available for TCP connections.
The following example shows how to migrate to the new API.
Old questdb 1.x code
from questdb.ingress import Sender
auth = (
'testUser1',
'5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48',
'token_x=fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU',
'token_y=Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac')
with Sender('localhost', 9009, auth=auth, tls=True) as sender:
sender.row(
'test_table',
symbols={'sym': 'AAPL'},
columns={'price': 100.0}) # `at=None` was defaulted for server timeEquivalent questdb 2.x code
from questdb.ingress import Sender, Protocol, ServerTimestamp
sender = Sender(
Protocol.Tcps,
'localhost',
9009,
username='testUser1',
token='5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48',
token_x='token_x=fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU',
token_y='token_y=Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac',
auto_flush_rows='off',
auto_flush_interval='off',
auto_flush_bytes=64512)
with sender:
sender.row(
'test_table',
symbols={'sym': 'AAPL'},
columns={'price': 100.0},
at=ServerTimestamp)Equivalent questdb 2.x code with configuration string
from questdb.ingress import Sender, ServerTimestamp
conf = (
'tcp::addr=localhost:9009;' +
'username=testUser1;' +
'token=5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48;' +
'token_x=token_x=fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU;' +
'token_y=token_y=Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac;' +
'auto_flush_rows=off;' +
'auto_flush_interval=off;' +
'auto_flush_bytes=64512;')
with Sender.from_conf(conf) as sender:
sender.row(
'test_table',
symbols={'sym': 'AAPL'},
columns={'price': 100.0},
at=ServerTimestamp)