Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
More devin feedback
Signed-off-by: Nick Quinn <nicholas_quinn@apple.com>
  • Loading branch information
nickquinn408 committed Jun 28, 2026
commit 970cbbcf4524106556ab6efd6afebae4a9a6d50c
9 changes: 8 additions & 1 deletion sdk/python/feast/infra/registry/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -1620,8 +1620,15 @@ def _list_objects(
with self.read_engine.begin() as conn:
stmt = select(table).where(table.c.project_id == project)
if updated_since is not None:
# Ensure naive datetimes are treated as UTC, consistent with
# the Python-side filters that compare against offset-naive UTC
# last_updated_timestamp values from protobuf.
if updated_since.tzinfo is None:
updated_since_utc = updated_since.replace(tzinfo=timezone.utc)
else:
updated_since_utc = updated_since.astimezone(timezone.utc)
stmt = stmt.where(
table.c.last_updated_timestamp >= int(updated_since.timestamp())
table.c.last_updated_timestamp >= int(updated_since_utc.timestamp())
)
Comment thread
nquinn408 marked this conversation as resolved.
rows = conn.execute(stmt).all()
if rows:
Expand Down
33 changes: 33 additions & 0 deletions sdk/python/tests/unit/infra/registry/test_sql_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,36 @@ def test_list_feature_views_updated_since(sqlite_registry):
"test_project", tags=None, updated_since=future
)
assert len(result) == 0


def test_list_feature_views_updated_since_naive_treated_as_utc(sqlite_registry):
"""A naive updated_since is treated as UTC, not local time, in the SQL filter."""
entity = Entity(
name="courier",
value_type=ValueType.STRING,
join_keys=["courier_id"],
)
sqlite_registry.apply_entity(entity, "test_project")

file_source = FileSource(
path="courier_stats.parquet",
timestamp_field="event_timestamp",
created_timestamp_column="created",
)

fv = _build_feature_view("courier_activity", entity, file_source)
sqlite_registry.apply_feature_view(fv, "test_project")

# A naive past cutoff (interpreted as UTC) should return the feature view
past_naive = datetime(2000, 1, 1)
result = sqlite_registry._list_feature_views(
"test_project", tags=None, updated_since=past_naive
)
assert any(fv.name == "courier_activity" for fv in result)

# The equivalent UTC-aware cutoff must produce the same result
past_aware = datetime(2000, 1, 1, tzinfo=timezone.utc)
result_aware = sqlite_registry._list_feature_views(
"test_project", tags=None, updated_since=past_aware
)
assert len(result) == len(result_aware)