python - 为什么 django 会在新创建的对象上给我一个 ObjectDoesNotExist 错误?

标签 python mysql django

我刚刚在测试一些使用 django 处理订单的代码时遇到了这个问题。尝试加载(按 ID)新创建的记录时出现“ObjectDoesNotExist”错误。

这是其工作原理的框架:

  • 有人下订单,其详细信息保存在名为“trader_order”的表中的记录中。
  • 该对象中的值用于在另一个表中创建记录(这与此处的问题无关,除了它们成功使用新订单的 ID 这一事实之外)。
  • 然后将订单记录的 ID 插入 FIFO 缓冲区。
  • 完成所有这些的功能然后发送一封电子邮件,然后结束。

另一个 Django 脚本正在读取 FIFO 缓冲区,该脚本正在等待将 ID 传递给它(作为守护进程在后台运行)。一旦收到该 ID,它就会尝试加载具有该 ID 的订单记录,并对其进行处理。

这一直运作良好(无论如何在测试中),直到今天的一个实例。我下了一个测试订单(没什么特别的),但收到一条错误消息,指出该记录不存在。我很困惑为什么。这是监视缓冲区的代码:

def handle(self, *args, **options):
    ###
    # code chopped out for brevity.  Just opening (successfully) the fifo buffer
    ###

    done = 0 
    str = ''
    while not done:
        chr = fifo.read(1);
        if(len(chr)):
            print "read %s" % chr 
            if(chr == ','):
                str = str.strip()
                if(str == 'quit'):
                    done = 1 
                elif(str.isdigit()):
                    print "We have a valid id: %s" % str 
                    self.process_order(str)
                str = ''
            else:
                str += chr 
        else:
            time.sleep(1)

    fifo.close()     

def process_order(self, order_id): 
    try:
        order = models.Order.objects.get(id=order_id)    
        print "Found Order:"
        print order
    except ObjectDoesNotExist:
        print "Order with id %s does not exist"%order_id
        return

    # code continues here, but is not relevant to the question

这是它在控制台上的输出:

read 1
read 2
read 3
read 1
read 6
read 7
read ,
We have a valid id: 123167
Order with id 123167 does not exist

当我查看数据库时,该 ID 确实存在。我不知道为什么它会给我那个错误。我也无法重现它。当我手动将相同的 id 传递到缓冲区时,它完美地处理了订单。当我尝试重现这种情况时,它再次完美运行。

这会不会是因为这两段代码分别连接到 MySQL 服务器?在监听脚本尝试从数据库中读取记录之前,可能需要刷新一些东西?

这里有一些相关的信息:

  • 我正在使用 django 的 manage.py ("./manage.py runserver 0.0.0.0:8000") 在测试环境中运行页面
  • 上面的代码也作为 manage.py ("./manage.py cronprocessorders") 的后台任务运行
  • 数据库是MySQL
  • 在 Ubuntu 发行版上运行

更新

根据提出的要求,这里有更多代码。这是实际下订单并将其 ID 放入上面代码正在读取的缓冲区的函数:

def order_place(self, order):
    '''Place and order on the system. The system will deduct the fee, escrow the amount and 
    create an unprocessed open order.
    '''
    balance = self.balance()
    for cur, bal in balance.items():
        limit = self.limit(cur, 'balance')
        if limit != None and bal > limit:
            raise BalanceLimit(limit, cur) 

    if order.order_total() > balance[order.currency_from()]:
        raise NotSufficientFunds

    order.profile = self 

    # Set up the fee for the order
    tr_fee = Transaction()
    tr_fee.profile = order.profile
    tr_fee.reason = 'fee'
    tr_fee.currency = order.currency_from()
    tr_fee.amount = -order.fee()
    tr_fee.notes = "%.2f%%" % (order.feerate())

    order.save()

    # Commit the fee now that the order is saved
    if tr_fee.amount < 0: 
        tr_fee.processed = datetime.datetime.now()
        tr_fee.order = order
        tr_fee.save()

    if order.remaining > 0: 
        # Put the remaining into escrow (debit)
        tr_da = Transaction()
        tr_da.profile = order.profile
        tr_da.processed = datetime.datetime.now()
        tr_da.reason = 'escrow'
        tr_da.order = order
        tr_da.currency = order.currency_from()
        tr_da.amount = -order.escrow()
        tr_da.save()   

    #write the order id to the FIFO process for order filling
    try: 
        fifo = open(settings.FIFO_PROCESS_ORDER_FILE_PATH, 'w+') 
        fifo.write('%s,' % order.id)
        fifo.close()
    except IOError:
        print "file doesn't exist"     

就是这样。回想起来,我在描述这个时看到了错误的功能(抱歉)。唯一的区别是最后发送的电子邮件。这个不这样做。传入的“订单”对象是已经清理过的表单数据。

哦,我为这些乱七八糟的变量名道歉。这不是我写的。

最佳答案

当您说您无法重现它时,这让我认为我们正在处理竞争条件。也许您将对象发送出去进行创建,然后在创建尚未完成时尝试读取它。它是在黑暗中刺探,但没有更多代码,就像@krelagin 所建议的那样,很难更好地了解发生了什么。

手边我看不出有什么乱七八糟的东西,但我不是 django 内部专家。我建议你看看this video关于保存后 iconfinder 关于 ObjectNotExist 的体验。整个视频值得一看,但链接会将您带到相关部分。

关于python - 为什么 django 会在新创建的对象上给我一个 ObjectDoesNotExist 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17094292/

相关文章:

Mysql 脚本用于删除每个现有表中存在零的所有行

python - 将函数从我的 django 方法中移出

python - 从另一个文件调用函数以在模板中使用

python - Python中有 '?'控制流吗?

python - 将多个字符串列转换为整数列表

python - 如何在 python 中定义 C-Enumeration 类型

mysql - SQL Date between 和另一个条件语句不起作用

javascript - 在级联选择框中从数据库中获取数据

django - 如何在 Django 查询集中找到不在另一个指定查询集中的实体?

python - 使用 MultiIndex 时如何将此 Pandas 列类型保留为日期时间?