Skip to content

feat: skip SQLAlchemy model fields with default values#845

Open
AlexPetul wants to merge 2 commits intolitestar-org:mainfrom
AlexPetul:feat/sqlalchemy-defaults
Open

feat: skip SQLAlchemy model fields with default values#845
AlexPetul wants to merge 2 commits intolitestar-org:mainfrom
AlexPetul:feat/sqlalchemy-defaults

Conversation

@AlexPetul
Copy link
Copy Markdown
Contributor

Description

Skip random value generation for SQLAlchemy fields that have a default value.

Although this works for most common cases, it has limitations for more advanced usage.
For example, context-sensitive default functions cannot be reliably evaluated:

def mydefault(context):
    return context.get_current_parameters()["counter"] + 12


t = Table(
    "mytable",
    metadata_obj,
    Column("counter", Integer),
    Column(
        "counter_plus_twelve",
        Integer,
        default=mydefault,
        onupdate=mydefault,
    ),
)

Such defaults require an execution context, and there is no obvious or safe way to construct a DefaultExecutionContext.

Similarly, SQL expressions used as defaults (for example text("select ...")) cannot be evaluated without a db round-trip, so they cannot be resolved at factory/build time.

This implementation only supports simple scalar defaults and callable defaults without context parameters.

Closes #837

@AlexPetul AlexPetul force-pushed the feat/sqlalchemy-defaults branch 2 times, most recently from 2e16752 to 1df2588 Compare March 25, 2026 12:16
@AlexPetul AlexPetul force-pushed the feat/sqlalchemy-defaults branch from 1df2588 to 99be865 Compare March 25, 2026 12:25
@AlexPetul AlexPetul marked this pull request as ready for review March 25, 2026 12:52
@AlexPetul AlexPetul requested a review from adhtruong as a code owner March 25, 2026 12:52
Copy link
Copy Markdown
Collaborator

@adhtruong adhtruong left a comment

Choose a reason for hiding this comment

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

Currently, the pattern used in other factories is to just detect that there is a default and omit supplying a value when this setting is on.

Does logic work if persistence is used? This may not be less complex though don't feel strongly on this given does feel clunkier to use

Comment thread polyfactory/factories/sqlalchemy_factory.py Outdated
@AlexPetul AlexPetul force-pushed the feat/sqlalchemy-defaults branch from d344902 to ebabc9c Compare April 2, 2026 06:45
Co-authored-by: Andrew Truong <40660973+adhtruong@users.noreply.github.com>
@AlexPetul AlexPetul force-pushed the feat/sqlalchemy-defaults branch 2 times, most recently from 6408a43 to b1e1221 Compare April 2, 2026 06:56
@AlexPetul
Copy link
Copy Markdown
Contributor Author

Currently, the pattern used in other factories is to just detect that there is a default and omit supplying a value when this setting is on.

Indeed, dataclasses, msgspec, etc. handle defaults at the runtime level, so omitting a value applies the default. But with alchemy it's different.

Behavior with persistence remains unchanged:

  • default is applied by SQLAlchemy before insert
  • server_default is applied by the database if the column is omitted

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.

Enhancement: Skip SQLAlchemy model fields with default values

2 participants