Skip to content

Commit ba2207d

Browse files
committed
Use Datetime for general DateTime
1 parent d708a56 commit ba2207d

File tree

3 files changed

+27
-23
lines changed

3 files changed

+27
-23
lines changed

test/test_core.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ def define_tables(cls, metadata: sa.MetaData):
213213
Table(
214214
"test_datetime_types",
215215
metadata,
216-
Column("datetime", sa.DateTime, primary_key=True),
217-
Column("datetime_tz", sa.DateTime(timezone=True)),
216+
Column("datetime", sa.DATETIME, primary_key=True),
217+
Column("datetime_tz", sa.DATETIME(timezone=True)),
218218
Column("timestamp", sa.TIMESTAMP),
219219
Column("timestamp_tz", sa.TIMESTAMP(timezone=True)),
220220
Column("date", sa.Date),
@@ -260,33 +260,35 @@ def test_datetime_types(self, connection: sa.Connection):
260260
)
261261

262262
result = connection.execute(stmt).fetchone()
263-
assert result == (b"Timestamp", b"Datetime", b"Timestamp")
263+
assert result == (b"Datetime", b"Datetime", b"Timestamp")
264264

265265
def test_datetime_types_timezone(self, connection: sa.Connection):
266266
table = self.tables.test_datetime_types
267+
tzinfo = datetime.timezone(datetime.timedelta(hours=3, minutes=42))
267268

268-
now_dt = datetime.datetime.now()
269-
now_dt_tz = now_dt.replace(tzinfo=datetime.timezone(datetime.timedelta(hours=3, minutes=42)))
270-
today = now_dt.date()
269+
timestamp_value = datetime.datetime.now()
270+
timestamp_value_tz = timestamp_value.replace(tzinfo=tzinfo)
271+
datetime_value = timestamp_value.replace(microsecond=0)
272+
datetime_value_tz = timestamp_value_tz.replace(microsecond=0)
273+
today = timestamp_value.date()
271274

272275
statement = sa.insert(table).values(
273-
datetime=now_dt,
274-
datetime_tz=now_dt_tz,
275-
timestamp=now_dt,
276-
timestamp_tz=now_dt_tz,
276+
datetime=datetime_value,
277+
datetime_tz=datetime_value_tz,
278+
timestamp=timestamp_value,
279+
timestamp_tz=timestamp_value_tz,
277280
date=today,
278281
# interval=datetime.timedelta(minutes=45),
279282
)
280283
connection.execute(statement)
281284

282285
row = connection.execute(sa.select(table)).fetchone()
283286

284-
now_dt_tz_utc = now_dt.replace(tzinfo=datetime.timezone.utc) - datetime.timedelta(hours=3, minutes=42)
285287
assert row == (
286-
now_dt,
287-
now_dt_tz_utc, # YDB doesn't store timezone, so it is always utc
288-
now_dt,
289-
now_dt_tz_utc, # YDB doesn't store timezone, so it is always utc
288+
datetime_value,
289+
datetime_value_tz.astimezone(datetime.timezone.utc), # YDB doesn't store timezone, so it is always utc
290+
timestamp_value,
291+
timestamp_value_tz.astimezone(datetime.timezone.utc), # YDB doesn't store timezone, so it is always utc
290292
today,
291293
)
292294

ydb_sqlalchemy/sqlalchemy/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ def visit_BINARY(self, type_: sa.BINARY, **kw):
132132
def visit_BLOB(self, type_: sa.BLOB, **kw):
133133
return "String"
134134

135-
def visit_datetime(self, type_: sa.TIMESTAMP, **kw):
136-
return self.visit_TIMESTAMP(type_, **kw)
135+
def visit_datetime(self, type_: sa.DATETIME, **kw):
136+
return self.visit_DATETIME(type_, **kw)
137137

138138
def visit_DATETIME(self, type_: sa.DATETIME, **kw):
139139
return "DateTime"
@@ -204,7 +204,7 @@ def get_ydb_type(
204204
elif isinstance(type_, sa.TIMESTAMP):
205205
ydb_type = ydb.PrimitiveType.Timestamp
206206
elif isinstance(type_, sa.DateTime):
207-
ydb_type = ydb.PrimitiveType.Timestamp
207+
ydb_type = ydb.PrimitiveType.Datetime
208208
elif isinstance(type_, sa.Date):
209209
ydb_type = ydb.PrimitiveType.Date
210210
elif isinstance(type_, sa.BINARY):
@@ -549,7 +549,7 @@ def upsert(table):
549549
ydb.PrimitiveType.Yson: sa.TEXT,
550550
ydb.PrimitiveType.Date: sa.DATE,
551551
ydb.PrimitiveType.Datetime: sa.DATETIME,
552-
ydb.PrimitiveType.Timestamp: sa.DATETIME,
552+
ydb.PrimitiveType.Timestamp: sa.TIMESTAMP,
553553
ydb.PrimitiveType.Interval: sa.INTEGER,
554554
ydb.PrimitiveType.Bool: sa.BOOLEAN,
555555
ydb.PrimitiveType.DyNumber: sa.TEXT,
@@ -619,7 +619,7 @@ class YqlDialect(StrCompileDialect):
619619
colspecs = {
620620
sa.types.JSON: types.YqlJSON,
621621
sa.types.JSON.JSONPathType: types.YqlJSON.YqlJSONPathType,
622-
sa.types.DateTime: types.YqlTimestamp,
622+
sa.types.DateTime: types.YqlDateTime,
623623
sa.types.DATETIME: types.YqlDateTime,
624624
sa.types.TIMESTAMP: types.YqlTimestamp,
625625
}

ydb_sqlalchemy/sqlalchemy/datetime_types.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,20 @@ def result_processor(self, dialect: Dialect, coltype: str) -> Optional[_ResultPr
1111
def process(value: Optional[datetime.datetime]) -> Optional[datetime.datetime]:
1212
if value is None:
1313
return None
14+
if not self.timezone:
15+
return value
1416
return value.replace(tzinfo=datetime.timezone.utc)
1517

16-
if self.timezone:
17-
return process
18-
return None
18+
return process
1919

2020

2121
class YqlDateTime(YqlTimestamp):
2222
def bind_processor(self, dialect: Dialect) -> Optional[_BindProcessorType[datetime.datetime]]:
2323
def process(value: Optional[datetime.datetime]) -> Optional[int]:
2424
if value is None:
2525
return None
26+
if not self.timezone: # if timezone is disabled, consider it as utc
27+
value = value.replace(tzinfo=datetime.timezone.utc)
2628
return int(value.timestamp())
2729

2830
return process

0 commit comments

Comments
 (0)