Skip to content

bug: Парметр типа datetime принимает int, но не принимает datetime #709

@senjaster

Description

@senjaster

Bug Report

YDB Python SDK version:

ydb==3.21.9

Environment

MacOS Sonoma, Macbook Pro M2, Python 3.13.5

Current behavior:

Параметр типа Datetime и Datetime64 требуют передавать на вход int (эпоху)
Это странно, кроме того для типа Datetime64 и отдаленных дат (типа 1000 год) нужно правильно конвертировать в эпоху, для этого нужно указать UTC, иначе конвертация в питоне даст некорректный результат.

Кроме того, если прочитать значение селектом, то оно вернется как datetime что совсем нелогично.

Expected behavior:

Можно передать Datetime и он сконвертируется автоматически.

Steps to reproduce:

Вот тесты:

from datetime import datetime, timezone
import ydb
import pytest


def test_select(pool):
    results = pool.execute_with_retries("SELECT datetime64('0001-01-01T00:00:00Z') as dt")
    for result in results:
        value = result.rows[0]['dt']
        assert value == datetime(year=1, month=1, day=1)

test_type_list = [
    ('datetime', ydb.PrimitiveType.Datetime),
    ('timestamp', ydb.PrimitiveType.Timestamp),
    ('datetime64', ydb.PrimitiveType.Datetime64),
    ('timestamp64', ydb.PrimitiveType.Timestamp64),
    
]
@pytest.mark.parametrize("test_type_name, test_type", test_type_list)
def test_parameter(pool, test_type_name, test_type):
    # Этот тест проходит для timestamp но не проходит для datetime
    
    value = datetime(year=1999, month=1, day=1)

    results = pool.execute_with_retries(
            f"DECLARE $dt_val AS {test_type_name};"
            "SELECT $dt_val AS dt;",
            parameters={"$dt_val": ydb.TypedValue(value, test_type)}
    )

    for result in results:
        result_value = result.rows[0]['dt']
        assert result_value == value



def test_parameter_workaround(pool):
    value = datetime(year=1, month=1, day=1)
    
    # Правильный способ конвертации
    value_epoch = int(value.replace(tzinfo=timezone.utc).timestamp())

    results = pool.execute_with_retries(
            "DECLARE $dt64_val AS datetime64;"
            "SELECT $dt64_val AS dt;",
            parameters={"$dt64_val": ydb.TypedValue(value_epoch, ydb.PrimitiveType.Datetime64)}
    )

    for result in results:
        result_value = result.rows[0]['dt']
        assert result_value == value

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions