Fields

The YDB backend supports most built-in Django fields. The table below is both the support status and the exact YDB type mapping for each field.

Legend: βœ… supported Β· 🟑 works with caveats (see the note) Β· ❌ unsupported or not enforced by YDB.

Field

YDB type

Python

Notes

AutoField / SmallAutoField / BigAutoField

βœ…

Serial family (Int32 / Int16 / Int64)

int

Value generated by YDB.

CharField, TextField, SlugField, EmailField

βœ…

Utf8

str

IPAddressField, GenericIPAddressField

βœ…

Utf8

str

BinaryField, FileField

βœ…

String

bytes

FilePathField

βœ…

Utf8

str

BooleanField

βœ…

Bool

bool

SmallIntegerField / IntegerField / BigIntegerField

βœ…

Int16 / Int32 / Int64

int

Signed integer chosen by range.

PositiveSmallIntegerField / PositiveIntegerField / PositiveBigIntegerField

βœ…

UInt16 / UInt32 / UInt64

int

Unsigned integer chosen by range.

FloatField

βœ…

Float

float

Cannot be a primary key.

DecimalField

βœ…

Decimal

Decimal

Arbitrary max_digits / decimal_places; values rounded to the field’s scale (YDB keeps ~26 significant digits).

UUIDField

βœ…

UUID

uuid.UUID

Native UUID.

DurationField

βœ…

Interval

int

Β±136 years; cannot be a primary key. Temporal subtraction supported.

DateField

βœ…

Date32

datetime.date

Signed wide date β€” dates before 1970 are supported.

DateTimeField

🟑

Timestamp64

datetime.datetime

Microsecond precision, instants before 1970. Under USE_TZ=False naive datetimes shift by the server timezone on round-trip; the production default USE_TZ=True is unaffected.

TimeField

🟑

Int64

datetime.time

No native time type β€” stored as microseconds since midnight, introspected back as BigIntegerField. __hour / __minute / __second lookups work.

JSONField

🟑

Json

dict / list / str / int / float / bool

Equality filtering (filter(data=value)) is not supported by YDB and the column cannot be introspected. null=True works, and __isnull filtering works.

Relationship fields

ForeignKey, OneToOneField, and ManyToManyField work through the Django ORM. A relation is stored as a plain scalar <name>_id column typed from the target’s primary key (ManyToManyField uses an ordinary through table); you define relations, query them, and traverse them with select_related (and prefetch_related, with a few edge cases) as usual.

What YDB does not do is enforce any of the relational guarantees at the database level:

  • no FOREIGN KEY / REFERENCES / ON DELETE is emitted or introspected;

  • there is no cascade delete at the database level β€” Django’s ORM on_delete still runs for ORM deletes, but raw SQL or external writers can orphan rows;

  • one-to-one and many-to-many-pair uniqueness is not enforced β€” the ORM declaration is accepted, but duplicates are not rejected.

Enforce these in application code (validate_unique(), clean(), validators) where you need them. For example:

class Product(models.Model):
    sku = models.CharField(max_length=20, primary_key=True)


class ProductReview(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    rating = models.IntegerField()

ProductReview.product is stored as a product_id column with the same YDB type as Product.sku. An insert writes the referenced key value only:

ProductReview.objects.create(product_id="SKU-1", rating=5)

YDB accepts this row even if no Product(sku="SKU-1") exists.