Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client.execute return [] insted of no of row insterted #221

Open
hackaholic opened this issue May 28, 2021 · 2 comments
Open

client.execute return [] insted of no of row insterted #221

hackaholic opened this issue May 28, 2021 · 2 comments

Comments

@hackaholic
Copy link

hackaholic commented May 28, 2021

Describe the bug
client.execute return [] instead of no of row insterted

To Reproduce
clickhouse-client

clickhouse :) CREATE TABLE IF NOT EXISTS test.pets (id UInt32, name String, eventTime DateTime) Engine = ReplicatedMergeTree('/clickhouse/iond_shard/test/tables/dd_pets/{shard}', '{replica}') PARTITION BY toYYYYMMDD(eventTime) ORDER BY (id,eventTime)

CREATE TABLE IF NOT EXISTS test.pets
(
    `id` UInt32,
    `name` String,
    `eventTime` DateTime
)
ENGINE = ReplicatedMergeTree('/clickhouse/iond_shard/test/tables/dd_pets/{shard}', '{replica}')
PARTITION BY toYYYYMMDD(eventTime)
ORDER BY (id, eventTime)

Query id: 12396bd5-4802-47d7-9acf-494a20bc9f81

Ok.

0 rows in set. Elapsed: 0.058 sec.

using python clickhouse driver to insert data:

>>> from clickhouse_driver import Client
>>> clickhouse_driver.VERSION
(0, 2, 0)
>>> c = Client("10.10.10.168")
>>> c.execute("show databases")
[('default',), ('system',), ('test',)]
>>> c.execute("insert into test.pets (id, name, eventTime) values(1, 'coco', '2021-04-26 18:07:13')")
[]
 >>> c.execute("select * from test.pets")
[(1, 'coco', datetime.datetime(2021, 4, 26, 18, 7, 13))]

Expected behavior
It should return no of inserted row
from the Doc: https://readthedocs.org/projects/clickhouse-driver/downloads/pdf/latest/

Versions

  • Version of package with the problem 0.2.0
  • Python version. python 3.6 & 3.8.5
@hackaholic
Copy link
Author

I can see in source code function are returning the inserted_rows
` def execute(self, query, params=None, with_column_types=False,
external_tables=None, query_id=None, settings=None,
types_check=False, columnar=False):
"""
Executes query.

    Establishes new connection if it wasn't established yet.
    After query execution connection remains intact for next queries.
    If connection can't be reused it will be closed and new connection will
    be created.

    :param query: query that will be send to server.
    :param params: substitution parameters for SELECT queries and data for
                   INSERT queries. Data for INSERT can be `list`, `tuple`
                   or :data:`~types.GeneratorType`.
                   Defaults to ``None`` (no parameters  or data).
    :param with_column_types: if specified column names and types will be
                              returned alongside with result.
                              Defaults to ``False``.
    :param external_tables: external tables to send.
                            Defaults to ``None`` (no external tables).
    :param query_id: the query identifier. If no query id specified
                     ClickHouse server will generate it.
    :param settings: dictionary of query settings.
                     Defaults to ``None`` (no additional settings).
    :param types_check: enables type checking of data for INSERT queries.
                        Causes additional overhead. Defaults to ``False``.
    :param columnar: if specified the result of the SELECT query will be
                     returned in column-oriented form.
                     It also allows to INSERT data in columnar form.
                     Defaults to ``False`` (row-like form).

    :return: * number of inserted rows for INSERT queries with data.
               Returning rows count from INSERT FROM SELECT is not
               supported.
             * if `with_column_types=False`: `list` of `tuples` with
               rows/columns.
             * if `with_column_types=True`: `tuple` of 2 elements:
                * The first element is `list` of `tuples` with
                  rows/columns.
                * The second element information is about columns: names
                  and types.
    """

    start_time = time()
    self.make_query_settings(settings)
    self.connection.force_connect()
    self.last_query = QueryInfo()

    try:
        # INSERT queries can use list/tuple/generator of list/tuples/dicts.
        # For SELECT parameters can be passed in only in dict right now.
        is_insert = isinstance(params, (list, tuple, types.GeneratorType))

        if is_insert:
            rv = self.process_insert_query(
                query, params, external_tables=external_tables,
                query_id=query_id, types_check=types_check,
                columnar=columnar
            )
        else:
            rv = self.process_ordinary_query(
                query, params=params, with_column_types=with_column_types,
                external_tables=external_tables,
                query_id=query_id, types_check=types_check,
                columnar=columnar
            )
        self.last_query.store_elapsed(time() - start_time)
        return rv

    except (Exception, KeyboardInterrupt):
        self.disconnect()
        raise



def process_insert_query(self, query_without_data, data,
                         external_tables=None, query_id=None,
                         types_check=False, columnar=False):
    self.connection.send_query(query_without_data, query_id=query_id)
    self.connection.send_external_tables(external_tables,
                                         types_check=types_check)

    sample_block = self.receive_sample_block()
    if sample_block:
        rv = self.send_data(sample_block, data,
                            types_check=types_check, columnar=columnar)
        self.receive_end_of_query()
        return rv

`

@hackaholic
Copy link
Author

I am able to get no of row Inserted if array of values is passed as separate argument.

c.execute("insert into test.pets (id, name, eventTime) VALUES", [(2, 'Mini', datetime.datetime.now()), (3, 'Dora', datetime.datetime.now())])
2

But if we pass complete query as string, then we have issue

xzkostyan added a commit that referenced this issue Sep 3, 2021
For inlined INSERTs and from INSERT INTO ... SELECT
xzkostyan added a commit that referenced this issue Sep 3, 2021
For inlined INSERTs and from INSERT INTO ... SELECT
xzkostyan added a commit that referenced this issue Sep 6, 2021
For inlined INSERTs and from INSERT INTO ... SELECT
xzkostyan added a commit that referenced this issue Sep 6, 2021
For inlined INSERTs and from INSERT INTO ... SELECT
xzkostyan added a commit that referenced this issue Sep 8, 2021
For inlined INSERTs and from INSERT INTO ... SELECT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant