Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add interface to overrideget_column_from_field |get_sqlalchemy_type function behavior #503

Open
Labels
featureNew feature or request
@243f6a8885a308d313198a2e037

Description

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the SQLModel documentation, with the integrated search.
  • I already searched in Google "How to X in SQLModel" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to SQLModel but toPydantic.
  • I already checked if it is not related to SQLModel but toSQLAlchemy.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

# current workaround: force extending sqlmodel.main.get_sqlalchemy_typefromtypingimportAny,Callableimportsqlmodel.mainfrompydanticimportBaseModel,ConstrainedStrfrompydantic.fieldsimportModelFieldfromsqlalchemyimportStringfromtyping_extensionsimportTypeAlias_GetSqlalchemyTypeProtocol:TypeAlias=Callable[[ModelField],Any]def_override_get_sqlalchemy_type(original_get_sqlalchemy_type:_GetSqlalchemyTypeProtocol,)->_GetSqlalchemyTypeProtocol:def_extended_get_sqlalchemy_type(field:ModelField)->Any:ifissubclass(field.type_,BaseModel):# TODO use sqlalchemy.JSON or CHAR(N) for "known to be short" modelsraiseNotImplementedError(field.type_)ifissubclass(field.type_,ConstrainedStr):# MAYBE add CHECK constraint for field.type_.regexlength=field.type_.max_lengthiflengthisnotNone:returnString(length=length)returnString()returnoriginal_get_sqlalchemy_type(field)return_extended_get_sqlalchemy_typesqlmodel.main.get_sqlachemy_type=_override_get_sqlalchemy_type(sqlmodel.main.get_sqlachemy_type)# MAYBE get_sqlachemy_type -> get_sqlalchemy_type (sqlmodel > 0.0.8)# cf. <https://github.com/tiangolo/sqlmodel/commit/267cd42fb6c17b43a8edb738da1b689af6909300>

Description

Problem:

  • We want to decide database column types deterministically by model field.
  • SometimesSQLModel does not provide expected column type, and it is (in some cases) impossible because requirements ofSQLModel users are not always the same (e.g. DBMS dialects, strictness of constraints, choice of CHAR vs VARCHAR vs TEXT vs JSON, TIMESTAMP vs DATETIME)

Wanted Solution

Allow user to use customizedget_column_from_field |get_sqlalchemy_type function to fit with their own requirements.

Add parameter to model config likesa_column_builder: Callable[[ModelField], Column] = get_column_from_field.

Functionget_column_from_field would be better split by the following concerns, to be used as a part of customizedsa_column_builder implementation:

  1. Deciding the column type (currently done inget_sqlalchemy_type)
  2. Applying pydantic field options to column type (e.g. nullable, min, max, min_length, max_length, regex, ...)
  3. Applying column options (e.g. primary_key, index, foreign_key, unique, ...)

Possible effects on other issues/PRs:


p.s-1

Conversion rule between Field/column value may become necessary, mainly to serialize field value to column value.
(e.g. Classes inheriting BaseModel cannot be stored directly intosqlalchemy.JSON because it is not JSON or dict. We avoid this by addingjson_serializer tocreate_engine. Deserialize part has no problem because JSONstr ->BaseModel will be done by pydantic validation for now (pydantic v1))

def_json_serializer(value:Any)->str:ifisinstance(value,BaseModel):returnvalue.json()returnjson.dumps(value)

p.s-2

IMO usingsqlmodel.sql.sqltypes.AutoString() in alembic revision file is not good from the sight of future migration constancy, and this is one of the reason I overriddenget_sqlalchemy_type function.

Wanted Code

################################################################# expected: any of the following `Foo` / `Bar`def_custom_sa_column_builder(field:ModelField)->Column:    ...classFoo(SQLModel,table=True):classSQLModelConfig:sa_column_builder:Callable[[ModelField],Column]=_custom_sa_column_builder    ...classBar(SQLModel,table=True,sa_column_builder=_custom_sa_column_builder):    ...

Alternatives

  • Write a function that returnssa_column and call it insqlmodel.Field declaration
    • -> Not easy to apply pydantic-side constraints (e.g. nullable,ConstrainedStr, ...)

Operating System

Linux

Operating System Details

No response

SQLModel Version

0.0.8

Python Version

3.10.7

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp