Skip to content

Enhancement: Support Ignoring SQLAlchemy Computed Columns When Generating Inserts (Build/Sync) #754

@brandon-sorrow

Description

@brandon-sorrow

Summary

It would be awesome if there was a config value we could pass to the BaseFactory instantiation that would detect SQLAlchemy Computed columns and exclude them from the INSERT statement on create_sync, create_async and build calls to the factory.

Setting a computed column to Ignore() in the factory still results in the generated INSERT trying to insert a None value to the generated column.

Basic Example

from sqlalchemy import Computed
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from polyfactory.factories.sqlalchemy_factory import SQLAlchemyFactory, T

class Some(DeclarativeBase):
    id: int = mapped_column(...)
    other_col: int = mapped_column(...)
    computed_col: int = mapped_column(
        Computed("id + other_col" , persisted=True),
        nullable=True,
    )

# Base Class
class BaseFactory(SQLAlchemyFactory[T]):
    __is_base_factory__ = True
    __session__ = SomeSession
    __async_session__ = SomeAsyncSession
    __min_collection_length__ = 3
    __set_relationships__ = False
    __set_association_proxy__ = False
    __check_model__ = False

class SomeFactory(BaseFactory[Some]): ...


SomeFactory.create_sync(id=10, other_col=10)

Doing this currently results in an error like:

def execute(
        self,
        query: Query,
        params: Params | None = None,
        *,
        prepare: bool | None = None,
        binary: bool | None = None,
    ) -> Self:
        """
        Execute a query or command to the database.
        """
        try:
            with self._conn.lock:
                self._conn.wait(
                    self._execute_gen(query, params, prepare=prepare, binary=binary)
                )
        except e._NO_TRACEBACK as ex:
>           raise ex.with_traceback(None)
E           psycopg.errors.GeneratedAlways: cannot insert a non-DEFAULT value into column "computed_col"
E           DETAIL:  Column "computed_col" is a generated column.

When using Postgres as the DB backend

Drawbacks and Impact

I'm not sure of any drawbacks, but it would make using computed columns possible when using PolyFactory.

Unresolved questions

Is there a workaround to accomplish this currently?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions