How to use Postgresql Array field in Tortoise-ORM

3.2k views Asked by At

Pretty much the title, I'm trying to setup Tortoise-ORM model that will include Field corresponding to Postgresql Array column.

It seems like to do it properly I'd need to build from asyncpg (since it has full array support) up extending Tortoise Field. However I'm just starting with Tortoise and maybe there's some better/easier way forward/someone already did something similar.

2

There are 2 answers

0
andnik On

You need to implement your own field type. Here is my implementation:


from typing import List, Union, Type, Optional, Any
import json

from tortoise.fields.base import Field
from tortoise.models import Model


class IntArrayField(Field, list):
    """
    Int Array field specifically for PostgreSQL.

    This field can store list of int values.
    """

    SQL_TYPE = "int[]"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def to_db_value(
        self, value: List[int], instance: "Union[Type[Model], Model]"
    ) -> Optional[List[int]]:
        return value

    def to_python_value(self, value: Any) -> Optional[List[int]]:
        if isinstance(value, str):
            array = json.loads(value.replace("'", '"'))
            return [int(x) for x in array]
        return value

I don't have dynamic type field implementation, which is not so difficult to make from this.

In some cases you need to put more logic into to_db_value and to_python_value casting. For instance, if you are using UUID[].

1
Gabriel On

You can now use ArrayField from the contrib part of tortoise (>= 0.19).

from tortoise.contrib.postgres.fields import ArrayField

int_array = ArrayField()
text_array = ArrayField(element_type="text")