Skip to content

[Bug]: vectorizer_relationship fails when table_args is a tuple instead of dict #799

@jw-cpnet

Description

@jw-cpnet

What happened?

When using vectorizer_relationship with a SQLAlchemy model that has table_args defined as a tuple (a common pattern for defining multiple constraints/indexes), the application
fails to start with the following error:

AttributeError: 'tuple' object has no attribute 'get'

Full traceback shows the error occurs in pgai/sqlalchemy/init.py at line 78:

table_args_schema_name = getattr(owner, "__table_args__", {}).get("schema")

Expected

The vectorizer_relationship should work with all valid SQLAlchemy table_args patterns. According to SQLAlchemy documentation, table_args can be:

  • A dictionary: table_args = {"schema": "myschema"}
  • A tuple with constraints/indexes: table_args = (UniqueConstraint(...), Index(...))
  • A tuple with constraints/indexes and a dict: table_args = (UniqueConstraint(...), Index(...), {"schema": "myschema"})

The code should handle the tuple case by checking the type of table_args and only calling .get() if it's a dictionary, or if it's a tuple, checking if the last element is a dictionary.

Environment:

  • pgai version: 0.10.1
  • SQLAlchemy version: 2.0.32
  • Python version: 3.12
  • Database: PostgreSQL with TimescaleDB and pgai extensions
  • Using asyncpg driver

Workaround:

Currently, I had to avoid using vectorizer_relationship and use raw SQL queries instead to work with the embeddings table/view.

pgai extension affected

No response

pgai library affected

No response

PostgreSQL version used

16

What operating system did you use?

ArchLinux

What installation method did you use?

Docker

What platform did you run on?

On prem/Self-hosted

Relevant log output and stack trace

How can we reproduce the bug?

Example code that triggers the error:


from pgai.sqlalchemy import vectorizer_relationship
from sqlalchemy import UniqueConstraint, Index
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

class Feature(DeclarativeBase):
    __tablename__ = "features"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]

    # This is a common SQLAlchemy pattern for multiple constraints
    __table_args__ = (
        UniqueConstraint("name", "tenant_id"),
        Index("ix_features_tenant_id", "tenant_id"),
    )

    # This causes the error
    embeddings = vectorizer_relationship(
        dimensions=1536,
        target_table="features_embeddings"
    )

Are you going to work on the bugfix?

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions