diff --git a/sdk/python/feast/infra/online_stores/sqlite.py b/sdk/python/feast/infra/online_stores/sqlite.py index 1b79b1a94b..e2eeb038d0 100644 --- a/sdk/python/feast/infra/online_stores/sqlite.py +++ b/sdk/python/feast/infra/online_stores/sqlite.py @@ -17,7 +17,7 @@ import sqlite3 import struct import sys -from datetime import datetime +from datetime import date, datetime from pathlib import Path from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union @@ -39,6 +39,46 @@ from feast.utils import _build_retrieve_online_document_record, to_naive_utc +def adapt_date_iso(val: date): + """Adapt datetime.date to ISO 8601 date.""" + return val.isoformat() + + +def adapt_datetime_iso(val: datetime): + """Adapt datetime.datetime to timezone-naive ISO 8601 date.""" + return val.isoformat() + + +def adapt_datetime_epoch(val: datetime): + """Adapt datetime.datetime to Unix timestamp.""" + return int(val.timestamp()) + + +sqlite3.register_adapter(date, adapt_date_iso) +sqlite3.register_adapter(datetime, adapt_datetime_iso) +sqlite3.register_adapter(datetime, adapt_datetime_epoch) + + +def convert_date(val: bytes): + """Convert ISO 8601 date to datetime.date object.""" + return date.fromisoformat(val.decode()) + + +def convert_datetime(val: bytes): + """Convert ISO 8601 datetime to datetime.datetime object.""" + return datetime.fromisoformat(val.decode()) + + +def convert_timestamp(val: bytes): + """Convert Unix epoch timestamp to datetime.datetime object.""" + return datetime.fromtimestamp(int(val)) + + +sqlite3.register_converter("date", convert_date) +sqlite3.register_converter("datetime", convert_datetime) +sqlite3.register_converter("timestamp", convert_timestamp) + + class SqliteOnlineStoreConfig(FeastConfigBaseModel, VectorStoreConfig): """Online store config for local (SQLite-based) store""" diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index 10ad007fa9..8a1c5b70c3 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -6,7 +6,7 @@ select = ["E","F","W","I"] ignore = ["E203", "E266", "E501", "E721"] [tool.ruff.lint.isort] -known-first-party = ["feast", "feast", "feast_serving_server", "feast_core_server"] +known-first-party = ["feast", "feast_serving_server", "feast_core_server"] default-section = "third-party" [tool.mypy] diff --git a/setup.py b/setup.py index 5ee1e891bc..05f57f6053 100644 --- a/setup.py +++ b/setup.py @@ -155,7 +155,7 @@ "build", "virtualenv==20.23.0", "cryptography>=35.0,<43", - "ruff>=0.3.3", + "ruff>=0.8.0", "mypy-protobuf>=3.1", "grpcio-tools>=1.56.2,<2", "grpcio-testing>=1.56.2,<2",