Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions api/app_analytics/migrations/0006_add_labels.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Generated by Django 4.2.21 on 2025-06-16 16:55

import django.contrib.postgres.fields.hstore
from django.contrib.postgres.operations import HStoreExtension
# import django.contrib.postgres.fields.hstore
# from django.contrib.postgres.operations import HStoreExtension

from django.db import migrations
from django.db import models


class Migration(migrations.Migration):
Expand All @@ -13,25 +14,37 @@ class Migration(migrations.Migration):
]

operations = [
HStoreExtension(),
# # The extension usage is annulated by the subsequent migration.
# # To avoid the operational overhead of enabling it in some environments,
# # we do not create it here anymore.
# # However, leave it commented out for reference/history.
# HStoreExtension(),
migrations.AddField(
model_name="apiusagebucket",
name="labels",
field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
# This field is now a JSONField instead of HStoreField.
# field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="apiusageraw",
name="labels",
field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
# This field is now a JSONField instead of HStoreField.
# field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="featureevaluationbucket",
name="labels",
field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
# This field is now a JSONField instead of HStoreField.
# field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="featureevaluationraw",
name="labels",
field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
# This field is now a JSONField instead of HStoreField.
# field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
field=models.JSONField(default=dict),
),
]
33 changes: 33 additions & 0 deletions api/app_analytics/migrations/0007_labels_jsonb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 4.2.22 on 2025-07-25 14:09

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("app_analytics", "0006_add_labels"),
]

operations = [
migrations.AlterField(
model_name="apiusagebucket",
name="labels",
field=models.JSONField(default=dict),
),
migrations.AlterField(
model_name="apiusageraw",
name="labels",
field=models.JSONField(default=dict),
),
migrations.AlterField(
model_name="featureevaluationbucket",
name="labels",
field=models.JSONField(default=dict),
),
migrations.AlterField(
model_name="featureevaluationraw",
name="labels",
field=models.JSONField(default=dict),
),
Copy link
Contributor

@emyller emyller Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my understanding, this will lead to multiple alter column ... type statements. Is casting hstore to json as simple as that in, at least, Postgres?

I'm also curious as to the impact of this to existing installs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, we actually need a USING clause. Added in 091006e.

]
7 changes: 3 additions & 4 deletions api/app_analytics/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from datetime import timedelta

from django.contrib.postgres.fields import HStoreField
from django.core.exceptions import ValidationError
from django.db import models
from django_lifecycle import ( # type: ignore[import-untyped]
Expand Down Expand Up @@ -59,7 +58,7 @@ class APIUsageRaw(models.Model):
host = models.CharField(max_length=255)
resource = models.IntegerField(choices=Resource.choices)
count = models.PositiveIntegerField(default=1)
labels = HStoreField(default=dict)
labels = models.JSONField(default=dict)

class Meta:
index_together = (("environment_id", "created_at"),)
Expand All @@ -70,7 +69,7 @@ class AbstractBucket(LifecycleModelMixin, models.Model): # type: ignore[misc]
created_at = models.DateTimeField()
total_count = models.PositiveIntegerField()
environment_id = models.PositiveIntegerField()
labels = HStoreField(default=dict)
labels = models.JSONField(default=dict)

class Meta:
abstract = True
Expand Down Expand Up @@ -107,7 +106,7 @@ class FeatureEvaluationRaw(models.Model):
environment_id = models.PositiveIntegerField()
evaluation_count = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
labels = HStoreField(default=dict)
labels = models.JSONField(default=dict)

# Both stored for tracking multivariate split testing.
identity_identifier = models.CharField(max_length=2000, null=True, default=None)
Expand Down
Loading