我正在开发一个Django应用程序,它可以帮助分析来自不同位置的发射器的无线电信号传播。原始数据从MySQL数据库获得,该数据库记录报告者接收的每个信号及其来源和时间戳。
想法是在特定时间间隔/块期间检查接收器相对于目标发射器的状态。过滤后的结果需要作为JSON文件返回。
# All records within the time frame in question
qs_spots = Spot.objects.filter(unix_time__range = (starttime, endtime))
qs_spots = qs_spots_all.values()
# the focus is on a particular transmitter tx
tx_dict = {}
tx_dict['tx_callsign'] = tx
interval_range = 120
# list of all unique receivers - the field is called 'reporter' in the model
rx_list = qs_spots.values_list('reporter', flat=True).distinct()
tx_dict['rx_total'] = len(rx_list)
tx_dict['receivers'] = []
# goes through each reporter in the list
for rx in rx_list:
rx_dict = {}
rx_dict['rx_callsign'] = rx
rx_spots = qs_spots.filter(reporter=rx)
rx_dict['time_state'] = []
current_time = starttime
while current_time <= endtime:
next_time = current_time + interval_range # increment next time interval
time_dict = {}
time_dict['datetime'] = current_time
rx_time = rx_spots.filter(unix_time__range = (current_time, next_time))
# first check if any records exist for the particular interval
if rx_time.exists():
# then check the transmitter status
if rx_time.filter(transmitter=tx).exists():
time_dict['status'] = 0 # reporter is receiving from target transmitter
else:
time_dict['status'] = 1 # reporter is not receiving from target transmitter, but is receiving from other transmitters
else:
# if no records exists for the particular interval
# i.e reporter is not receiving at all during this interval
time_dict['status'] = 2
current_time = next_time # set to next interval
rx_dict['time_state'].append(time_dict.copy())
tx_dict['receivers'].append(rx_dict.copy())
response = json.dumps(tx_dict, cls=DjangoJSONEncoder)
return HttpResponse(response, content_type='application/json')
我自己测试了外环并且它工作正常,虽然很慢 - 在30秒到2分钟之间返回50-100个接收器的JSON列表。当我添加内部循环以检查目标变送器的状态时,问题就来了。即使在数小时后,结果也永远不会恢复。
我已尝试过各种时间范围,但我的“默认”是在1小时窗口内以约120秒(2分钟)的间隔约50个接收器。 50 *(60/2)=总共1500个循环。对于计算机而言,听起来并不是很重要,但有些东西导致它被锁定。
编辑:添加了我的models.py(如果有帮助)
class Spot(models.Model):
spot_id = models.IntegerField(db_column='Spot_ID', primary_key=True) # Field name made lowercase.
unix_time = models.IntegerField(db_column='UNIX_time', blank=True, null=True) # Field name made lowercase.
reporter = models.CharField(db_column='Reporter', max_length=15, blank=True, null=True) # Field name made lowercase.
transmitter = models.CharField(db_column='Transmitter', max_length=15, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'SPOT'
编辑2: 尝试将查询集转换为字典并限制字段
qs_spots = qs_spots.values('unix_time', 'reporter', 'transmitter')
rx_spots = qs_spots.filter(reporter=rx).values('unix_time', 'reporter', 'transmitter')
rx_time = rx_spots.filter(unix_time__range = (current_time, next_time)).values('transmitter')
外部循环似乎运行得更快,但内部循环仍然被锁定。
预期的JSON响应示例
{
"tx_callsign": "EA4DUT",
"rx_total": 3,
"receivers": [
{
"rx_callsign": "G1RWT"
"time_state": [
{ "datetime": 1443963600, "status": 0 },
{ "datetime": 1443963720, "status": 1 },
{ "datetime": 1443963840, "status": 2 }
]
},
{
"rx_callsign": "PI4THT"
"time_state": [
{ "datetime": 1443963600, "status": 1 },
{ "datetime": 1443963720, "status": 0 },
{ "datetime": 1443963840, "status": 2 }
]
},
{
"rx_callsign": "EI6KD"
"time_state": [
{ "datetime": 1443963600, "status": 2 },
{ "datetime": 1443963720, "status": 0 },
{ "datetime": 1443963840, "status": 0 }
]
},
]
}