ydb-platform / ydb-python-sdk

YDB Python SDK
https://ydb-platform.github.io/ydb-python-sdk/
Apache License 2.0
84 stars 46 forks source link

feature: Support time with timezone types #405

Open rekby opened 5 months ago

rekby commented 5 months ago
driver_config = ydb.DriverConfig(
    'grpc://ydb-ru.yandex.net:2135', '/ru/tutorial/home/testdb',
    credentials=ydb.credentials_from_env_variables(),
    root_certificates=ydb.load_ydb_root_certificate(),
)
with ydb.Driver(driver_config) as driver:
    driver.wait(timeout=15)
    with ydb.SessionPool(driver) as pool:
        result = pool.retry_operation_sync(lambda session: session.transaction().execute("select DateTime::MakeTzDatetime(air_date) from episodes;", commit_tx=True))
        print(result[0].rows)

Result:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File ".../.venv/lib/python3.11/site-packages/ydb/table.py", line 2492, in retry_operation_sync
    return retry_operation_sync(wrapped_callee, retry_settings)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/table.py", line 967, in retry_operation_sync
    for next_opt in opt_generator:
  File ".../.venv/lib/python3.11/site-packages/ydb/table.py", line 928, in retry_operation_impl
    result = YdbRetryOperationFinalResult(callee(*args, **kwargs))
                                          ^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/table.py", line 2490, in wrapped_callee
    return callee(session, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<stdin>", line 4, in <lambda>
  File ".../.venv/lib/python3.11/site-packages/ydb/table.py", line 2229, in execute
    return self._driver(
           ^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/tracing.py", line 70, in wrapper
    return f(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/pool.py", line 443, in __call__
    res = connection(
          ^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/connection.py", line 465, in __call__
    return response if wrap_result is None else wrap_result(rpc_state, response, *wrap_args)
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/_session_impl.py", line 20, in decorator
    return func(rpc_state, response_pb, session_state, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/_tx_ctx_impl.py", line 9, in decorator
    return func(rpc_state, response_pb, session_state, tx_state, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/_tx_ctx_impl.py", line 22, in decorator
    return func(rpc_state, response_pb, session_state, tx_state, query, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/_tx_ctx_impl.py", line 171, in wrap_result_and_tx_id
    return convert.ResultSets(message.result_sets, session_state.table_client_settings)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/convert.py", line 466, in __init__
    result_set = initializer(result_set, table_client_settings)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/convert.py", line 324, in from_message
    row[column.name] = column_parser(unwrapped_type, value, table_client_settings)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.venv/lib/python3.11/site-packages/ydb/convert.py", line 51, in _pb_to_primitive
    return _primitive_type_by_id.get(type_pb.type_id).get_value(value_pb, table_client_settings)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_value'

Expected result: query executed succesfully and print date

rekby commented 4 months ago

Initial research result:

Python doesn't have builtin timezone database and doesn't support history of timezone changes https://docs.python.org/3/library/datetime.html#timezone-objects

It isn't simple add new converter - it need to decide how match timezone name to timezone, what do with historical changes of TZ. How did it in windows (it hasn't builtin tzinfo database).

May be it need additional dependency for solve the task.