Skip to content

Commit

Permalink
feat(sqlalchemy-factory): add SQLAlchemy custom types section to docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bc291 committed Oct 7, 2023
1 parent 16d0c93 commit 19918fa
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import datetime
from typing import Any

from sqlalchemy import DateTime, types
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

from polyfactory.factories.sqlalchemy_factory import SQLAlchemyFactory


class TZAwareDateTime(types.TypeDecorator):
impl = DateTime(timezone=True)


class Base(DeclarativeBase):
...


class Author(Base):
__tablename__ = "authors"

id: Mapped[int] = mapped_column(primary_key=True)
first_publication_at: Mapped[Any] = mapped_column(type_=TZAwareDateTime(), nullable=False)


class AuthorFactory(SQLAlchemyFactory[Author]):
__model__ = Author


def test_sqla_type_decorator_custom_type_factory() -> None:
author = AuthorFactory.build()
assert isinstance(author.first_publication_at, datetime.datetime)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import datetime
from typing import Any, Callable, Dict

from sqlalchemy import types
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

from polyfactory.factories.sqlalchemy_factory import SQLAlchemyFactory


class CustomType(types.UserDefinedType):
...


class Base(DeclarativeBase):
...


class Author(Base):
__tablename__ = "authors"

id: Mapped[int] = mapped_column(primary_key=True)
first_publication_at: Mapped[Any] = mapped_column(type_=CustomType())


class AuthorFactory(SQLAlchemyFactory[Author]):
__model__ = Author

@classmethod
def get_sqlalchemy_types(cls) -> Dict[Any, Callable[[], Any]]:
return {**super().get_sqlalchemy_types(), CustomType: lambda: cls.__faker__.date_time()}


def test_sqla_user_defined_type_custom_type_factory() -> None:
author = AuthorFactory.build()
assert isinstance(author.first_publication_at, datetime.datetime)
23 changes: 23 additions & 0 deletions docs/usage/library_factories/sqlalchemy_factory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ By default, this will add generated models to the session and then commit. This

Similarly for ``__async_session__`` and ``create_async``.

SQLAlchemy custom types
------------------------------

TypeDecorator based
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Type will be inferred from SQLAlchemy type defined in ``impl``.

.. literalinclude:: /examples/library_factories/sqlalchemy_factory/test_example_4.py
:caption: Custom types with TypeDecorator
:language: python


UserDefinedType based
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``get_sqlalchemy_types`` classmethod needs to be overridden to provide factory function for custom type.

.. literalinclude:: /examples/library_factories/sqlalchemy_factory/test_example_5.py
:caption: Custom types with TypeDecorator
:language: python

More info on `SQLAlchemy Custom Types <https://docs.sqlalchemy.org/en/20/core/custom_types.html>`_

API reference
------------------------------
Expand Down

0 comments on commit 19918fa

Please sign in to comment.