Используя Postgres Speci c ArrayField, я пытаюсь суммировать длины ArrayFields.
Запросы отлично работают в оболочке, но не на локальном сервере разработки. Я сузил ошибку до последней аннотации в строке 19: «annotate (total = Sum (« length »))», видя, как она работает без этого последнего .annotate (...). Values (...) part.
Я также запустил «makemigrations» и «migrate», чтобы база данных была обновлена.
Ошибка:
psycopg2.errors.InvalidCursorName: cursor " _django_curs_19180_1 "не существует
курсор" _django_curs_19180_1 "не существует
Отладочный вывод:
('SELECT "product_design_assembledfromcomponent"."id", '
'"product_design_assembledfromcomponent"."assembled_id_id", '
'"product_design_assembledfromcomponent"."quantity", '
'"product_design_assembledfromcomponent"."designed_with_id_id", '
'"product_design_assembledfromcomponent"."position", '
'"product_design_assembledfromcomponent"."description", '
'"product_design_assembledfromcomponent"."assembled_inhouse", (SELECT '
'SUM(ARRAY_LENGTH(U0."position")) AS "total" FROM "product_design_multistep" '
'U0 WHERE U0."assembly_id" = ("product_design_assembledfromcomponent"."id") '
'GROUP BY U0."assembly_id" LIMIT 1) AS "taken" FROM '
'"product_design_assembledfromcomponent" WHERE '
'"product_design_assembledfromcomponent"."assembled_id_id" = %s')
The above exception (function array_length(character varying[]) does not exist LINE 1: ...edfromcomponent"."assembled_inhouse", (SELECT SUM(ARRAY_LENG... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. ) was the direct cause of the following exception:
Код:
1 from django.db.models import Q, Sum, Count, Subquery, OuterRef
2 from django_postgres_extensions.models.functions import ArrayLength
3
4 class ProductionStepForm(forms.ModelForm):
5 helper = FormHelper()
6 helper.layout = Layout(
7 Div("assemblies", "description",
8 css_class="col-md-7",
9 ),
10 )
11
12 helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))
13
14
15 def __init__(self, *args, **kwargs):
16 design = kwargs.pop("design")
17 super(ProductionStepForm, self).__init__(*args, **kwargs)
18
19 taken = MultiStep.objects.filter(assembly=OuterRef("id")).annotate(length=ArrayLength("position")).values("assembly").annotate(total=Sum("length")).values("total")
20 assembly_query = AssembledFromComponent.objects.filter(assembled_id=design).annotate(taken=Subquery(taken[:1]))
21 self.fields["assemblies"] = forms.ModelMultipleChoiceField(queryset=assembly_query, required=False)
22 self.Meta.fields.append("assemblies")
23
24
25 class Meta:
26 model = ProductionStep
27 fields = [
28 "description"
29 ]
Заранее спасибо за любую помощь!
Редактировать : Добавлены модели
1 class MultiStep(models.Model):
2 step = models.ForeignKey(ProductionStep, on_delete=models.PROTECT, null=True, blank=True)
3 assembly = models.ForeignKey(AssembledFromComponent, on_delete=models.PROTECT, null=True, blank=True)
4 quantity = models.DecimalField(decimal_places=6, max_digits=12, default=1)
5 position = ArrayField(
models.CharField(max_length=10, blank=True),
size=40,
blank=True,
null=True,
help_text="A subset of the set of positions defined for an assembly"
)
6 class AssembledFromComponent(models.Model):
7 # ID of the new component
8 assembled_id = models.ForeignKey(
9 DesignedComponent,
10 on_delete=models.PROTECT,
11 related_name='assembled_id'
12 )
13 quantity = models.DecimalField(decimal_places=6, max_digits=12)
14 # ID of a component used to make a new component
15 designed_with_id = models.ForeignKey(
16 DesignedComponent,
17 on_delete=models.PROTECT,
18 related_name='designed_with_id'
19 )
20 position = models.CharField(
21 max_length=200,
22 blank=True,
23 null=True,
24 help_text="Enter a single position or a comma separated list of positions with length = quantity"
25 )
26 description = models.TextField(
27 max_length=1000,
28 help_text='Enter a brief description of the assembly',
29 null=True,
30 blank=True,
31 )
32 assembled_inhouse = models.BooleanField(default=False)
Редактировать2: Вместо этого я сделаю поле MultiStep.position Atomi c, а не ArrayField, это делает вещи менее сложными.
Я все еще думаю, что оригинальная проблема любопытна, поскольку мне кажется, что длины массива не суммируемы.