简体   繁体   English

Django Max函数未返回最大值

[英]Django Max Function not returning Maximum Value

I need the maximum value of a particular field in my database, increment it by 1 and that becomes my new order number. 我需要数据库中特定字段的最大值,将其递增1,这将成为我的新订单号。

The way I do that is: 我这样做的方式是:

def generate_order_number(self):
    q_number = Order.objects.all().aggregate(Max('number'))['number__max']
    if q_number:
        q_number += 1
    else:
        q_number = 1

    return q_number

This code works perfectly fine until order number 10. However, when order number 11 is attempted, the aggregate query returns max value as 9 and thus, the function returns 10 as the new order number - which fails the entire process (number is unique in the database). 此代码工作完全正常,直到顺序号10。然而,当顺序号11尝试,所述aggregate查询返回最大值为9,因此,该函数返回10作为新的顺序号-其失败的整个过程(数是unique在数据库)。

Why would this be happening? 为什么会这样呢?

I am using Django/PostgreSQL combination. 我正在使用Django / PostgreSQL组合。 My database entry for number is: 我的数据库条目number是:

number = models.BigIntegerField(
    _("Quotation number"), db_index=True, unique=True)

Also, when I try to directly manipulate the database for order number, the error I get is: 另外,当我尝试直接为订单号操作数据库时,出现的错误是:

ProgrammingError at /admin/order/order/21/
operator does not exist: character varying = integer
LINE 1: ..._order" WHERE ("order_order"."number" = 11 AND N...
                                                         ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

How do I fix this? 我该如何解决?

The PostgreSQL serial datatype internally creates both a smallint / int / bigint column and a sequence. PostgreSQL serial数据类型在内部创建smallint / int / bigint列和序列。 Effectively making it equivalent to a normal int column with a default set to some sequence. 有效地使其等效于默认设置为某些序列的普通int列。

For example, this: 例如,这:

CREATE TABLE tablename (
    colname SERIAL
);

Internally results in this: 内部导致以下结果:

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

This is where your question comes in, while a plain CREATE SEQUENCE just adds a simple sequence that increments by one and will never go down. 这是您问题的出处,而普通的CREATE SEQUENCE只是添加一个简单的序列,该序列递增1,并且永远不会下降。 Using setval you can reset the sequence current value to reuse old numbers. 使用setval可以重置序列当前值以重用旧数字。

Do note that this can result in duplicate key constraints since the primary key will still be unique so if you do get duplicate key constraints, simply reset the sequence to a range that isn't in use yet ( SELECT MAX(colname)+1 FROM tablename should give you a correct startpoint). 请注意,这可能会导致重复的键约束,因为主键仍然是唯一的,因此,如果您确实获得了重复的键约束,只需将序列重置为尚未使用的范围( SELECT MAX(colname)+1 FROM tablename应为您提供正确的起点)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM