GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix: Normalize SQL registry read_path to the psycopg3 driver like path by larrysingleton007 · Pull Request #6644 · feast-dev/feast

fix: Normalize SQL registry read_path to the psycopg3 driver like path #6644

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
ntkathole merged 3 commits into feast-dev:master from larrysingleton007:fix/sql-registry-read-path-normalization
Jul 30, 2026

Uh oh!

There was an error while loading. Please reload this page.

Merged

fix: Normalize SQL registry read_path to the psycopg3 driver like path #6644

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
3 commits
Select commit Hold shift + click to select a range
622b582
fix: Normalize SQL registry read_path to the psycopg3 driver like path
larrysingleton007 Jul 24, 2026
bf0a742
test: Cover prefix-only PostgreSQL scheme normalization
franciscojavierarceo Jul 27, 2026
e08fa87
fix: Address review feedback on read_path validator
larrysingleton007 Jul 30, 2026
File filter
Filter by extension

Clear filters
Conversations
Failed to load comments.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Jump to
Jump to file
Failed to load files.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Diff view
Diff view

There are no files selected for viewing

11 changes: 10 additions & 1 deletion 11 sdk/python/feast/infra/registry/sql.py
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional, Union, cast

from pydantic import StrictInt, StrictStr
from pydantic import StrictInt, StrictStr, field_validator
from sqlalchemy import ( # type: ignore
BigInteger,
Column,
Expand Down Expand Up @@ -306,6 +306,15 @@ class SqlRegistryConfig(RegistryConfig):
thread_pool_executor_worker_count: StrictInt = 0
""" int: Number of worker threads to use for asynchronous caching in SQL Registry. If set to 0, it doesn't use ThreadPoolExecutor. """

@field_validator("read_path")
def validate_read_path(cls, read_path: Optional[str]) -> Optional[str]:
# Mirror `RegistryConfig.validate_path`: a bare `postgresql://` read_path
# must be rewritten to the psycopg3 driver too, otherwise it silently
# falls back to psycopg2 while `path` uses psycopg3.
if read_path is not None:
return cls._normalize_postgres_scheme(read_path, "read_path")
return read_path


class SqlRegistry(CachingRegistry):
def __init__(
Expand Down
34 changes: 24 additions & 10 deletions 34 sdk/python/feast/repo_config.py
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,33 @@ class RegistryConfig(FeastBaseModel):
mcp: Optional[McpRegistryConfig] = None
""" McpRegistryConfig: MCP (Model Context Protocol) configuration for the registry REST server. """

@staticmethod
def _normalize_postgres_scheme(value: str, field_name: str) -> str:
"""Rewrite a bare ``postgresql://`` URL to the psycopg3 driver, with a warning.

SQLAlchemy resolves a bare ``postgresql://`` to the psycopg2 driver, while
feast standardizes on psycopg3 (``postgresql+psycopg``). Pass an explicit
``postgresql+psycopg2`` to keep psycopg2. Shared by the ``path`` and
``read_path`` validators so both endpoints normalize identically.
"""
if value.startswith("postgresql://"):
_logger.warning(
f"The `{field_name}` of the `RegistryConfig` starts with a plain "
"`postgresql` string. We are updating this to `postgresql+psycopg` "
"to ensure that the `psycopg3` driver is used by `sqlalchemy`. If "
f"you want to use `psycopg2` pass `postgresql+psycopg2` explicitly "
f"to `{field_name}`. To silence this warning, pass `postgresql+psycopg` "
f"explicitly to `{field_name}`."
)
# Rewrite only the leading scheme, not any later occurrence (e.g.
# inside credentials or a query string).
return "postgresql+psycopg://" + value[len("postgresql://") :]
return value

@field_validator("path")
def validate_path(cls, path: str, values: ValidationInfo) -> str:
if values.data.get("registry_type") == "sql":
if path.startswith("postgresql://"):
_logger.warning(
"The `path` of the `RegistryConfig` starts with a plain "
"`postgresql` string. We are updating this to `postgresql+psycopg` "
"to ensure that the `psycopg3` driver is used by `sqlalchemy`. If "
"you want to use `psycopg2` pass `postgresql+psycopg2` explicitely "
"to `path`. To silence this warning, pass `postgresql+psycopg` "
"explicitely to `path`."
)
return path.replace("postgresql://", "postgresql+psycopg://")
return cls._normalize_postgres_scheme(path, "path")
return path


Expand Down
66 changes: 66 additions & 0 deletions 66 sdk/python/tests/unit/infra/registry/test_sql_registry.py
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,72 @@ def shared_sqlite_db_path():
yield path


def test_read_path_normalizes_bare_postgresql_scheme(caplog):
"""A bare `postgresql://` read_path is rewritten to the psycopg3 driver, the
same way `path` is, and logs a migration warning. Without this, read_path
silently falls back to psycopg2 while path uses psycopg3."""
with caplog.at_level(logging.WARNING):
config = SqlRegistryConfig(
registry_type="sql",
path="postgresql://localhost:5432/db",
read_path="postgresql://localhost:5432/replica",
)
assert config.path == "postgresql+psycopg://localhost:5432/db"
assert config.read_path == "postgresql+psycopg://localhost:5432/replica"
# The migration warning names the read_path field specifically.
assert "`read_path` of the `RegistryConfig`" in caplog.text


def test_read_path_normalized_when_registry_type_defaulted():
"""read_path normalization must still fire when registry_type is left to its
default ('sql') rather than passed explicitly — the common real-world config."""
config = SqlRegistryConfig(
path="postgresql://localhost/db",
read_path="postgresql://localhost/replica",
)
assert config.registry_type == "sql"
assert config.read_path == "postgresql+psycopg://localhost/replica"


@pytest.mark.parametrize(
"read_path",
[
"postgresql+psycopg2://localhost/replica", # explicit psycopg2 preserved
"postgresql+psycopg://localhost/replica", # already psycopg3
"mysql://localhost/replica", # non-postgres left untouched
],
)
def test_read_path_leaves_explicit_scheme_untouched(read_path):
config = SqlRegistryConfig(
registry_type="sql",
path="sqlite:///unused.db",
read_path=read_path,
)
assert config.read_path == read_path


def test_read_path_none_stays_none():
config = SqlRegistryConfig(registry_type="sql", path="sqlite:///unused.db")
assert config.read_path is None


@pytest.mark.parametrize("field_name", ["path", "read_path"])
def test_postgres_normalization_only_rewrites_leading_scheme(field_name):
raw_url = "postgresql://localhost/db?target=postgresql://replica"
config_values = {
"registry_type": "sql",
"path": "sqlite:///unused.db",
}
config_values[field_name] = raw_url

config = SqlRegistryConfig(**config_values)

assert (
getattr(config, field_name)
== "postgresql+psycopg://localhost/db?target=postgresql://replica"
)


def test_proto_columns_use_longblob_on_mysql():
"""On MySQL and MariaDB, serialized-proto columns must compile to LONGBLOB.

Expand Down
Loading
Oops, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.