|  | 
|  | 1 | +import pytest | 
|  | 2 | +import ydb | 
|  | 3 | + | 
|  | 4 | +from datetime import date, datetime, timedelta, timezone | 
|  | 5 | +from decimal import Decimal | 
|  | 6 | +from uuid import uuid4 | 
|  | 7 | + | 
|  | 8 | + | 
|  | 9 | +@pytest.mark.parametrize( | 
|  | 10 | +    "value,ydb_type_str,ydb_type", | 
|  | 11 | +    [ | 
|  | 12 | +        (True, "Bool", ydb.PrimitiveType.Bool), | 
|  | 13 | +        (-125, "Int8", ydb.PrimitiveType.Int8), | 
|  | 14 | +        (None, "Int8?", ydb.OptionalType(ydb.PrimitiveType.Int8)), | 
|  | 15 | +        (-32766, "Int16", ydb.PrimitiveType.Int16), | 
|  | 16 | +        (-1123, "Int32", ydb.PrimitiveType.Int32), | 
|  | 17 | +        (-2157583648, "Int64", ydb.PrimitiveType.Int64), | 
|  | 18 | +        (255, "UInt8", ydb.PrimitiveType.Uint8), | 
|  | 19 | +        (65534, "UInt16", ydb.PrimitiveType.Uint16), | 
|  | 20 | +        (5555, "UInt32", ydb.PrimitiveType.Uint32), | 
|  | 21 | +        (2157583649, "UInt64", ydb.PrimitiveType.Uint64), | 
|  | 22 | +        (3.1415, "Double", ydb.PrimitiveType.Double), | 
|  | 23 | +        (".31415926535e1", "DyNumber", ydb.PrimitiveType.DyNumber), | 
|  | 24 | +        (Decimal("3.1415926535"), "Decimal(28, 10)", ydb.DecimalType(28, 10)), | 
|  | 25 | +        (b"Hello, YDB!", "String", ydb.PrimitiveType.String), | 
|  | 26 | +        ("Hello, 🐍!", "Utf8", ydb.PrimitiveType.Utf8), | 
|  | 27 | +        ('{"foo": "bar"}', "Json", ydb.PrimitiveType.Json), | 
|  | 28 | +        (b'{"foo"="bar"}', "Yson", ydb.PrimitiveType.Yson), | 
|  | 29 | +        ('{"foo":"bar"}', "JsonDocument", ydb.PrimitiveType.JsonDocument), | 
|  | 30 | +        (uuid4(), "Uuid", ydb.PrimitiveType.UUID), | 
|  | 31 | +        ([1, 2, 3], "List<Int8>", ydb.ListType(ydb.PrimitiveType.Int8)), | 
|  | 32 | +        ({1: None, 2: None, 3: None}, "Set<Int8>", ydb.SetType(ydb.PrimitiveType.Int8)), | 
|  | 33 | +        ([b"a", b"b", b"c"], "List<String>", ydb.ListType(ydb.PrimitiveType.String)), | 
|  | 34 | +        ({"a": 1001, "b": 1002}, "Dict<Utf8, Int32>", ydb.DictType(ydb.PrimitiveType.Utf8, ydb.PrimitiveType.Int32)), | 
|  | 35 | +        ( | 
|  | 36 | +            ("a", 1001), | 
|  | 37 | +            "Tuple<Utf8, Int32>", | 
|  | 38 | +            ydb.TupleType().add_element(ydb.PrimitiveType.Utf8).add_element(ydb.PrimitiveType.Int32), | 
|  | 39 | +        ), | 
|  | 40 | +        ( | 
|  | 41 | +            {"foo": True, "bar": None}, | 
|  | 42 | +            "Struct<foo:Bool?, bar:Int32?>", | 
|  | 43 | +            ydb.StructType() | 
|  | 44 | +            .add_member("foo", ydb.OptionalType(ydb.PrimitiveType.Bool)) | 
|  | 45 | +            .add_member("bar", ydb.OptionalType(ydb.PrimitiveType.Int32)), | 
|  | 46 | +        ), | 
|  | 47 | +        (100, "Date", ydb.PrimitiveType.Date), | 
|  | 48 | +        (100, "Date32", ydb.PrimitiveType.Date32), | 
|  | 49 | +        (-100, "Date32", ydb.PrimitiveType.Date32), | 
|  | 50 | +        (100, "Datetime", ydb.PrimitiveType.Datetime), | 
|  | 51 | +        (100, "Datetime64", ydb.PrimitiveType.Datetime64), | 
|  | 52 | +        (-100, "Datetime64", ydb.PrimitiveType.Datetime64), | 
|  | 53 | +        (-100, "Interval", ydb.PrimitiveType.Interval), | 
|  | 54 | +        (-100, "Interval64", ydb.PrimitiveType.Interval64), | 
|  | 55 | +        (100, "Timestamp", ydb.PrimitiveType.Timestamp), | 
|  | 56 | +        (100, "Timestamp64", ydb.PrimitiveType.Timestamp64), | 
|  | 57 | +        (-100, "Timestamp64", ydb.PrimitiveType.Timestamp64), | 
|  | 58 | +        (1511789040123456, "Timestamp", ydb.PrimitiveType.Timestamp), | 
|  | 59 | +        (1511789040123456, "Timestamp64", ydb.PrimitiveType.Timestamp64), | 
|  | 60 | +        (-1511789040123456, "Timestamp64", ydb.PrimitiveType.Timestamp64), | 
|  | 61 | +    ], | 
|  | 62 | +) | 
|  | 63 | +def test_types(driver_sync: ydb.Driver, value, ydb_type_str, ydb_type): | 
|  | 64 | +    settings = ( | 
|  | 65 | +        ydb.QueryClientSettings() | 
|  | 66 | +        .with_native_date_in_result_sets(False) | 
|  | 67 | +        .with_native_datetime_in_result_sets(False) | 
|  | 68 | +        .with_native_timestamp_in_result_sets(False) | 
|  | 69 | +        .with_native_interval_in_result_sets(False) | 
|  | 70 | +        .with_native_json_in_result_sets(False) | 
|  | 71 | +    ) | 
|  | 72 | +    with ydb.QuerySessionPool(driver_sync, query_client_settings=settings) as pool: | 
|  | 73 | +        result = pool.execute_with_retries( | 
|  | 74 | +            f"DECLARE $param as {ydb_type_str}; SELECT $param as value", | 
|  | 75 | +            {"$param": (value, ydb_type)}, | 
|  | 76 | +        ) | 
|  | 77 | +        assert result[0].rows[0].value == value | 
|  | 78 | + | 
|  | 79 | + | 
|  | 80 | +test_td = timedelta(microseconds=-100) | 
|  | 81 | +test_now = datetime.utcnow() | 
|  | 82 | +test_old_date = datetime(1221, 1, 1, 0, 0) | 
|  | 83 | +test_today = test_now.date() | 
|  | 84 | +test_dt_today = datetime.today() | 
|  | 85 | +tz4h = timezone(timedelta(hours=4)) | 
|  | 86 | + | 
|  | 87 | + | 
|  | 88 | +@pytest.mark.parametrize( | 
|  | 89 | +    "value,ydb_type_str,ydb_type,result_value", | 
|  | 90 | +    [ | 
|  | 91 | +        # FIXME: TypeError: 'datetime.datetime' object cannot be interpreted as an integer | 
|  | 92 | +        # (test_dt_today, "Datetime", test_dt_today), | 
|  | 93 | +        (test_today, "Date", ydb.PrimitiveType.Date, test_today), | 
|  | 94 | +        (365, "Date", ydb.PrimitiveType.Date, date(1971, 1, 1)), | 
|  | 95 | +        (-365, "Date32", ydb.PrimitiveType.Date32, date(1969, 1, 1)), | 
|  | 96 | +        (3600 * 24 * 365, "Datetime", ydb.PrimitiveType.Datetime, datetime(1971, 1, 1, 0, 0)), | 
|  | 97 | +        (3600 * 24 * 365 * (-1), "Datetime64", ydb.PrimitiveType.Datetime64, datetime(1969, 1, 1, 0, 0)), | 
|  | 98 | +        (datetime(1970, 1, 1, 4, 0, tzinfo=tz4h), "Timestamp", ydb.PrimitiveType.Timestamp, datetime(1970, 1, 1, 0, 0)), | 
|  | 99 | +        (test_td, "Interval", ydb.PrimitiveType.Interval, test_td), | 
|  | 100 | +        (test_td, "Interval64", ydb.PrimitiveType.Interval64, test_td), | 
|  | 101 | +        (test_now, "Timestamp", ydb.PrimitiveType.Timestamp, test_now), | 
|  | 102 | +        (test_old_date, "Timestamp64", ydb.PrimitiveType.Timestamp64, test_old_date), | 
|  | 103 | +        ( | 
|  | 104 | +            1511789040123456, | 
|  | 105 | +            "Timestamp", | 
|  | 106 | +            ydb.PrimitiveType.Timestamp, | 
|  | 107 | +            datetime.fromisoformat("2017-11-27 13:24:00.123456"), | 
|  | 108 | +        ), | 
|  | 109 | +        ('{"foo": "bar"}', "Json", ydb.PrimitiveType.Json, {"foo": "bar"}), | 
|  | 110 | +        ('{"foo": "bar"}', "JsonDocument", ydb.PrimitiveType.JsonDocument, {"foo": "bar"}), | 
|  | 111 | +    ], | 
|  | 112 | +) | 
|  | 113 | +def test_types_native(driver_sync, value, ydb_type_str, ydb_type, result_value): | 
|  | 114 | +    with ydb.QuerySessionPool(driver_sync) as pool: | 
|  | 115 | +        result = pool.execute_with_retries( | 
|  | 116 | +            f"DECLARE $param as {ydb_type_str}; SELECT $param as value", | 
|  | 117 | +            {"$param": (value, ydb_type)}, | 
|  | 118 | +        ) | 
|  | 119 | +        assert result[0].rows[0].value == result_value | 
0 commit comments