Skip to content

2.0.0

Compare
Choose a tag to compare
@amunra amunra released this 19 Mar 15:50
· 29 commits to main since this release
8e4b407

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_CONF environment 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 protocol parameter 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 the row and dataframe methods 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 the ServerTimestamp singleton to this parameter. The ServerTimestamp behavior is considered legacy.

  • The auth=(u, t, x, y) argument of the Sender constructor has now been broken up into multiple arguments: username, token, token_x, token_y.

  • The tls argument of the Sender constructor has been removed and replaced with the protocol argument. Use Protocol.Tcps (or Protocol.Https) to enable TLS. The tls values have been moved to new tls_ca and tls_roots configuration settings.

  • The net_interface argument of the Sender constructor has been renamed to bind_interface and 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 time

Equivalent 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)