我只是在测试一些使用 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"
就是这样。回想起来,我在描述这个时看到了错误的函数(对不起)。唯一的区别是最后发送的电子邮件。这个不这样做。传入的“订单”对象是已经清除的表单数据。
哦,我为这些古怪的变量名道歉。这不是我写的。