tl; dr:阅读最后一段
我有一个函数应该在列表中返回三个row
个对象。行对象如下:
mining
中的savestate
process
分别为1,2或3
finish_date
采矿与savestates没有直接关系,所以我必须通过名为turn
的表来追踪正确的savestate。关系如下:savestate 1:n转1:1采矿。
这是我到目前为止所做的:
def get_latest_minings(save_id):
return_list = []
#get all turn.ids that belong to this savestate:
savestate_turns = [s.id for s in db(db.turn.savestate_id == save_id).select(db.turn.id)]
#get all minings that belong to these turns:
save_minings = db(db.mining.turn_id.belongs(savestate_turns)).select()
#loop to get three objects:
for i in range(1,4):
#from save_minings, get all minings, whose process is i:
line_minings = save_minings.find(lambda row: row.process == i)
#initialize loop variables:
latest_date = 0
latest = None
#loop to find the biggest finish_date:
for m in line_minings:
if m.finish_date > latest_date:
latest_date = m.finish_date
latest = m
#add the row with the biggest finish_date to the list:
return_list.append(latest)
#return locals() for testing purposes:
return locals()
#actual return:
#return return_list
然而,这并不像预期的那样起作用。这就是它的回报:
https://www.dropbox.com/s/ns6mq9414vw25s9/get_latest_minings.png?dl=0
我已经运行了一些单独的测试,我发现问题与行:line_minings = save_minings.find(lambda row: row.process == i)
有关。每一条线路都应该工作。这有什么不对?另一个问题:这可以更优化吗?我对追踪正确的savestate特别好奇。
答案 0 :(得分:1)
关于您的第一个问题What is wrong here?
:
流程的字段类型是否可能设置为string
或text
或integer
以外的其他任何内容?
您的第二个问题can this be optimized more?
:是的。大概。
如果没有剩下的代码,请点击这里:
def get_latest_minings(save_id):
# from the minings that belong to this savestate:
query = (db.mining.turn_id == db.turn.id) & (db.turn.savestate_id == save_id)
# [optional] if you want to restrict the process ids only to be 1,2 or 3.
# given your output, you only have 1 and 2 so it would be useless
# again, mind the datatype, don't compare strings to integers.
# but for completion, i'll stick to your original functionality
query &= (db.mining.process.belongs([1,2,3]))
# get the latest finish date per mining process
maxdate = db.mining.finish_date.max()
save_minings = db(query).select(maxdate, db.mining.process, groupby=db.mining.process)
# create a lookup structure with processid as key
last_date_lookup = {row.mining.process:row[maxdate] for row in save_minings}
# query the lookup structure per process id or None if not available
return [last_date_lookup.get(pid) for pid in range(1,4)]
当然没有经过测试,甚至没有解析或其他任何东西,但我希望它有所帮助。
还要记住,web2py的DAL可能无法找到某个字段。我注意到,在查询连接表时,需要以不同方式查询返回的行。大多数情况下,您可以在使用表名而不是row.mining.process
的{{1}}中看到这一点,这在查询row.process
表时非常有用。