Skip to content

feat: Add feature view versioning support to PostgreSQL and MySQL online stores#6193

Open
YassinNouh21 wants to merge 1 commit intofeast-dev:masterfrom
YassinNouh21:feat/postgres-mysql-versioning
Open

feat: Add feature view versioning support to PostgreSQL and MySQL online stores#6193
YassinNouh21 wants to merge 1 commit intofeast-dev:masterfrom
YassinNouh21:feat/postgres-mysql-versioning

Conversation

@YassinNouh21
Copy link
Copy Markdown
Collaborator

@YassinNouh21 YassinNouh21 commented Mar 29, 2026

Summary

  • Added versioned read/write support to PostgreSQL and MySQL online stores, following the SQLite reference implementation pattern from feat: Add version tracking to FeatureView #6101
  • When enable_online_feature_view_versioning is enabled, data is routed to version-specific tables (e.g., project_driver_stats_v2)
  • Registered both stores in _check_versioned_read_support() so version-qualified feature references (driver_stats@v2:trips_today) work correctly

Changes

PostgreSQL (postgres.py):

  • Updated _table_id() to accept enable_versioning parameter with version suffix logic
  • Updated all 6 callers: online_write_batch, _construct_query_and_params, update, teardown, retrieve_online_documents, retrieve_online_documents_v2

MySQL (mysql.py):

  • Updated _table_id() with same versioning pattern
  • Threaded enable_versioning through _execute_batch(), write_to_table(), and _drop_table_and_index()
  • Updated online_read, update, and teardown callers

Shared (online_store.py, errors.py):

  • Added PostgreSQLOnlineStore and MySQLOnlineStore to _check_versioned_read_support() allowlist
  • Updated VersionedOnlineReadNotSupported error message

Test plan

  • 7 unit tests for PostgreSQL _table_id (no version, disabled, enabled, v0, version_tag priority)
  • 7 unit tests for MySQL _table_id (same coverage)
  • 5 unit tests for _check_versioned_read_support (PostgreSQL/MySQL/SQLite allowed, unsupported raises, no tag no error)
  • 4 PostgreSQL e2e tests with real database (testcontainers): write/read without versioning, with v1, version isolation, teardown
  • 4 MySQL e2e tests with real database (testcontainers): same coverage
  • 27/27 tests passing, all lint checks pass

Closes #6168
Closes #6169
Part of #2728


Open with Devin

@YassinNouh21 YassinNouh21 requested review from a team as code owners March 29, 2026 12:56
@YassinNouh21 YassinNouh21 requested review from dmartinol, nquinn408 and redhatHameed and removed request for a team March 29, 2026 12:56
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

@YassinNouh21 YassinNouh21 force-pushed the feat/postgres-mysql-versioning branch 2 times, most recently from 744eaa9 to b35410f Compare March 29, 2026 13:12
…ine stores

Add versioned read/write support so that version-qualified feature references
(e.g., driver_stats@v2:trips_today) resolve to the correct versioned table in
both PostgreSQL and MySQL online stores.

Changes:
- PostgreSQL: Updated _table_id() and all callers to support enable_versioning
- MySQL: Updated _table_id(), _execute_batch(), write_to_table(), and
  _drop_table_and_index() to thread versioning flag through
- online_store.py: Registered PostgreSQLOnlineStore and MySQLOnlineStore in
  _check_versioned_read_support()
- errors.py: Updated VersionedOnlineReadNotSupported message
- Unit tests split per store in tests/unit/infra/online_store/
- Integration tests in tests/integration/online_store/ (Docker, testcontainers)

Closes feast-dev#6168
Closes feast-dev#6169
Part of feast-dev#2728

Signed-off-by: yassinnouh21 <yassinnouh21@gmail.com>
@YassinNouh21 YassinNouh21 force-pushed the feat/postgres-mysql-versioning branch from b35410f to 0e56ae2 Compare March 29, 2026 13:17
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 8 additional findings in Devin Review.

Open in Devin Review

Comment on lines +259 to +267
from feast.infra.online_stores.mysql_online_store.mysql import (
MySQLOnlineStore,
)
from feast.infra.online_stores.postgres_online_store.postgres import (
PostgreSQLOnlineStore,
)
from feast.infra.online_stores.sqlite import SqliteOnlineStore

if isinstance(self, SqliteOnlineStore):
if isinstance(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Unconditional import of optional dependencies (pymysql/psycopg) breaks all online reads

The _check_versioned_read_support method unconditionally imports MySQLOnlineStore (which triggers import pymysql) and PostgreSQLOnlineStore (which triggers from psycopg import ...) at the top of the method body. Both pymysql and psycopg are optional extras (defined in pyproject.toml under mysql and postgres groups), not core dependencies. Since _check_versioned_read_support is called unconditionally from both get_online_features (online_store.py:191) and get_online_features_async (online_store.py:320), any user using a different online store (e.g., DynamoDB, Redis, Bigtable) who does not have pymysql or psycopg installed will get an ImportError/ModuleNotFoundError on every online feature read — even non-versioned reads. This completely breaks the online serving path for those users.

Suggested change
from feast.infra.online_stores.mysql_online_store.mysql import (
MySQLOnlineStore,
)
from feast.infra.online_stores.postgres_online_store.postgres import (
PostgreSQLOnlineStore,
)
from feast.infra.online_stores.sqlite import SqliteOnlineStore
if isinstance(self, SqliteOnlineStore):
if isinstance(
from feast.infra.online_stores.sqlite import SqliteOnlineStore
supported_types = [SqliteOnlineStore]
try:
from feast.infra.online_stores.mysql_online_store.mysql import (
MySQLOnlineStore,
)
supported_types.append(MySQLOnlineStore)
except ImportError:
pass
try:
from feast.infra.online_stores.postgres_online_store.postgres import (
PostgreSQLOnlineStore,
)
supported_types.append(PostgreSQLOnlineStore)
except ImportError:
pass
if isinstance(self, tuple(supported_types)):
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add feature view versioning support to MySQL online store Add feature view versioning support to PostgreSQL online store

1 participant