diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml index 0042ff07..ac5f2cf8 100644 --- a/bindings/python/Cargo.toml +++ b/bindings/python/Cargo.toml @@ -13,10 +13,11 @@ name = "databend_driver" doc = false [dependencies] +chrono = { version = "0.4.35", default-features = false } ctor = "0.2.5" databend-driver = { workspace = true, features = ["rustls", "flight-sql"] } once_cell = "1.18" -pyo3 = { version = "0.21", features = ["abi3-py37"] } +pyo3 = { version = "0.21", features = ["abi3-py37", "chrono"] } pyo3-asyncio = { version = "0.21", features = ["tokio-runtime"] } tokio = "1.34" tokio-stream = "0.1" diff --git a/bindings/python/src/types.rs b/bindings/python/src/types.rs index 824f3ffd..dd71ad18 100644 --- a/bindings/python/src/types.rs +++ b/bindings/python/src/types.rs @@ -14,6 +14,7 @@ use std::sync::Arc; +use chrono::{NaiveDate, NaiveDateTime}; use once_cell::sync::Lazy; use pyo3::exceptions::{PyException, PyStopAsyncIteration, PyStopIteration}; use pyo3::intern; @@ -68,12 +69,12 @@ impl IntoPy for Value { v.into_py(py) } databend_driver::Value::Timestamp(_) => { - let s = self.0.to_string(); - s.into_py(py) + let t = NaiveDateTime::try_from(self.0).unwrap(); + t.into_py(py) } databend_driver::Value::Date(_) => { - let s = self.0.to_string(); - s.into_py(py) + let d = NaiveDate::try_from(self.0).unwrap(); + d.into_py(py) } databend_driver::Value::Array(inner) => { let list = PyList::new_bound(py, inner.into_iter().map(|v| Value(v).into_py(py))); diff --git a/bindings/python/tests/asyncio/steps/binding.py b/bindings/python/tests/asyncio/steps/binding.py index 0ba230fb..e55ed0f2 100644 --- a/bindings/python/tests/asyncio/steps/binding.py +++ b/bindings/python/tests/asyncio/steps/binding.py @@ -13,6 +13,7 @@ # limitations under the License. import os +from datetime import datetime, date from decimal import Decimal from behave import given, when, then @@ -74,13 +75,13 @@ async def _(context): # Map row = await context.conn.query_row("select {'xx':to_date('2020-01-01')}") - assert row.values() == ({"xx": "2020-01-01"},) + assert row.values() == ({"xx": date(2020, 1, 1)},) # Tuple row = await context.conn.query_row( "select (10, '20', to_datetime('2024-04-16 12:34:56.789'))" ) - assert row.values() == ((10, "20", "2024-04-16 12:34:56.789"),) + assert row.values() == ((10, "20", datetime(2024, 4, 16, 12, 34, 56, 789)),) @then("Select numbers should iterate all rows") @@ -110,9 +111,9 @@ async def _(context): async for row in rows: ret.append(row.values()) expected = [ - (-1, 1, 1.0, "1", "1", "2011-03-06", "2011-03-06 06:20:00"), - (-2, 2, 2.0, "2", "2", "2012-05-31", "2012-05-31 11:20:00"), - (-3, 3, 3.0, "3", "2", "2016-04-04", "2016-04-04 11:30:00"), + (-1, 1, 1.0, "1", "1", date(2011, 3, 6), datetime(2011, 3, 6, 6, 20)), + (-2, 2, 2.0, "2", "2", date(2012, 5, 31), datetime(2012, 5, 31, 11, 20)), + (-3, 3, 3.0, "3", "2", date(2016, 4, 4), datetime(2016, 4, 4, 11, 30)), ] assert ret == expected @@ -134,8 +135,8 @@ async def _(context): async for row in rows: ret.append(row.values()) expected = [ - (-1, 1, 1.0, "1", "1", "2011-03-06", "2011-03-06 06:20:00"), - (-2, 2, 2.0, "2", "2", "2012-05-31", "2012-05-31 11:20:00"), - (-3, 3, 3.0, "3", "2", "2016-04-04", "2016-04-04 11:30:00"), + (-1, 1, 1.0, "1", "1", date(2011, 3, 6), datetime(2011, 3, 6, 6, 20)), + (-2, 2, 2.0, "2", "2", date(2012, 5, 31), datetime(2012, 5, 31, 11, 20)), + (-3, 3, 3.0, "3", "2", date(2016, 4, 4), datetime(2016, 4, 4, 11, 30)), ] assert ret == expected diff --git a/bindings/python/tests/blocking/steps/binding.py b/bindings/python/tests/blocking/steps/binding.py index 42d632af..963cd2f7 100644 --- a/bindings/python/tests/blocking/steps/binding.py +++ b/bindings/python/tests/blocking/steps/binding.py @@ -13,6 +13,7 @@ # limitations under the License. import os +from datetime import datetime, date from decimal import Decimal from behave import given, when, then @@ -69,13 +70,13 @@ async def _(context): # Map row = context.conn.query_row("select {'xx':to_date('2020-01-01')}") - assert row.values() == ({"xx": "2020-01-01"},) + assert row.values() == ({"xx": date(2020, 1, 1)},) # Tuple row = context.conn.query_row( "select (10, '20', to_datetime('2024-04-16 12:34:56.789'))" ) - assert row.values() == ((10, "20", "2024-04-16 12:34:56.789"),) + assert row.values() == ((10, "20", datetime(2024, 4, 16, 12, 34, 56, 789)),) @then("Select numbers should iterate all rows") @@ -103,9 +104,9 @@ def _(context): for row in rows: ret.append(row.values()) expected = [ - (-1, 1, 1.0, "1", "1", "2011-03-06", "2011-03-06 06:20:00"), - (-2, 2, 2.0, "2", "2", "2012-05-31", "2012-05-31 11:20:00"), - (-3, 3, 3.0, "3", "2", "2016-04-04", "2016-04-04 11:30:00"), + (-1, 1, 1.0, "1", "1", date(2011, 3, 6), datetime(2011, 3, 6, 6, 20)), + (-2, 2, 2.0, "2", "2", date(2012, 5, 31), datetime(2012, 5, 31, 11, 20)), + (-3, 3, 3.0, "3", "2", date(2016, 4, 4), datetime(2016, 4, 4, 11, 30)), ] assert ret == expected @@ -126,8 +127,8 @@ def _(context): for row in rows: ret.append(row.values()) expected = [ - (-1, 1, 1.0, "1", "1", "2011-03-06", "2011-03-06 06:20:00"), - (-2, 2, 2.0, "2", "2", "2012-05-31", "2012-05-31 11:20:00"), - (-3, 3, 3.0, "3", "2", "2016-04-04", "2016-04-04 11:30:00"), + (-1, 1, 1.0, "1", "1", date(2011, 3, 6), datetime(2011, 3, 6, 6, 20)), + (-2, 2, 2.0, "2", "2", date(2012, 5, 31), datetime(2012, 5, 31, 11, 20)), + (-3, 3, 3.0, "3", "2", date(2016, 4, 4), datetime(2016, 4, 4, 11, 30)), ] assert ret == expected