Reputation: 571
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.
Upvotes: 5
Views: 3912
Reputation: 41
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")
Upvotes: 4
Reputation: 2804
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[]
.
Upvotes: 3