【问题标题】:Django psycopg2 cursor does not existDjango psycopg2 游标不存在
【发布时间】:2020-01-19 19:35:02
【问题描述】:

使用 Postgres 特定的 ArrayField,我试图对 ArrayFields 的长度求和。

查询在 shell 中可以正常工作,但在本地开发服务器上却不行。我已将错误缩小到第 19 行的最后一个注释:“annotate(total=Sum("length"))”,因为没有最后一个 .annotate(...).values(...)部分。

我还运行了“makemigrations”和“migrate”以便更新数据库。

错误:

psycopg2.errors.InvalidCursorName:游标“_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)

Edit2:我将改为使 MultiStep.position 字段原子而不是使用 ArrayField,这使事情变得不那么复杂。

我仍然认为原始问题很奇怪,因为在我看来,数组长度似乎不可求和。

【问题讨论】:

  • 什么是位置字段,如果您想了解更多关于您的模型的信息,也会很有帮助

标签: django postgresql psycopg2


【解决方案1】:

从错误看来,您的位置参数不是数组类型,而是字符类型。

(function array_length(**character varying[]**) does not exist 

array_length 函数只接受数组类型作为参数

【讨论】:

  • 似乎获取数组长度不是问题,而是对数组长度求和。至少代码运行良好,并且在不求和时给出数组长度。
猜你喜欢
  • 2013-10-04
  • 2021-05-04
  • 2015-08-06
  • 2020-09-24
  • 2015-08-11
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多