将多个一对多关系合并到json-oracle-python中



我的公司正在使用10.1 oracle数据库。

DB结构主表(主键(第二表(带主键的外键(第三个表(带主键的外键(

第二个表可能有0-4个链接条目第三个表可能有0-无限(虽然不可能超过20(

我的SQL查询运行良好,获取数据也很好。如果我们在其他表中获得多个条目,它将只返回具有相同主键的多行。似乎是标准的(对于SQL来说是新的,所以我认为它应该是这样的(。

问题是,当我尝试将数据处理成一个在所有内容上循环的单一JSON条目时。以下是我目前的脚本:

cursor = conn.cursor()
sql = """
SELECT *
FROM RC_CAL 
join CALENDAR_EVENT 
ON RC_CAL.rc_id = CALENDAR_EVENT.rc_id
left outer join CALENDAR_EVENT CALENDAR_EVENT_1 
ON RC_CAL.rc_id = CALENDAR_EVENT_1.rc_id 
left outer join RC_HISTORY RC_HISTORY_1 
ON RC_CAL.rc_id = RC_HISTORY_1.rc_id
"""
has_where = False
params = {}
query_conditions = []
if is_active:
has_where = True
query_conditions.append('WHERE CALENDAR_EVENT.ACTIVE_YN = :ACTIVE')
params['ACTIVE'] = is_active
if env:
env_string = 'AND CALENDAR_EVENT.env = :ENV' if has_where else 'WHERE CALENDAR_EVENT.env = :ENV'
has_where = True
query_conditions.append(env_string)
params['ENV'] = env
if from_date:
from_string = 'AND CALENDAR_EVENT.end_dt >= :FROM_DATE' if has_where else 'WHERE CALENDAR_EVENT.end_dt >= :FROM_DATE'
has_where = True
query_conditions.append(from_string)
params['FROM_DATE'] = from_date
if to_date:
to_string = 'AND CALENDAR_EVENT.end_dt <= :TO_DATE' if has_where else 'WHERE CALENDAR_EVENT.end_dt <= :TO_DATE'
query_conditions.append(to_string)
params['TO_DATE'] = to_date
if len(query_conditions) > 0:
sql += " ".join(query_conditions)
cursor.execute(sql, **params)
rows = cursor.fetchall()
events = []
for rcId, data in groupby(rows, key=lambda t: t[0]):
rc_item = None
generic_list = []
history_list = []
for item in data:
if not rc_item:
rc_item = EventModalV2(*item[0:11])
generic_id = item[11]
history_id = item[17]
generic_data = item[11:17]
history_data = item[17:]
if not any(generic_id in generic_item for generic_item in generic_list) and generic_id:
rc_item.update_with_generic(generic_data)
generic_list.append(generic_data)
if not any(history_id in history_item for history_item in history_list) and history_id:
rc_item.update_with_history(history_data)
history_list.append(history_data)

events.append(rc_item)
cursor.close()
conn.close()
return events

一个示例数据集,如果我有多个表3条目,尽管如果表2给出更多条目,可能会有更多条目(其中它说PROD,这是表2的一部分。这是一个我们根据环境存储日期的表PROD:

(170079, 3, 1, None, None, None, 'Test Demo Event - DS', 'N', 'N', None, datetime.datetime(2020, 11, 5, 19, 16, 22), 237247, datetime.datetime(2020, 11, 1, 4, 0), 'PROD', datetime.datetime(2020, 11, 1, 4, 0), 91, 'Y', 5051, <cx_Orac
le.LOB object at 0x00000237AE8954B8>, 'rc_create', datetime.datetime(2020, 11, 5, 19, 16, 22))

(170079, 3, 1, None, None, None, 'Test Demo Event - DS', 'N', 'N', None, datetime.datetime(2020, 11, 5, 19, 16, 22), 237247, datetime.datetime(2020, 11, 1, 4, 0), 'PROD', datetime.datetime(2020, 11, 1, 4, 0), 91, 'Y', 5052, <cx_Orac
le.LOB object at 0x00000237AE895580>, 'rc_patch', datetime.datetime(2020, 11, 5, 19, 17, 7))

(170079, 3, 1, None, None, None, 'Test Demo Event - DS', 'N', 'N', None, datetime.datetime(2020, 11, 5, 19, 16, 22), 237247, datetime.datetime(2020, 11, 1, 4, 0), 'PROD', datetime.datetime(2020, 11, 1, 4, 0), 91, 'Y', 5053, <cx_Orac
le.LOB object at 0x00000237AE895648>, 'rc_patch', datetime.datetime(2020, 11, 5, 19, 17, 59))

(170079, 3, 1, None, None, None, 'Test Demo Event - DS', 'N', 'N', None, datetime.datetime(2020, 11, 5, 19, 16, 22), 237247, datetime.datetime(2020, 11, 1, 4, 0), 'PROD', datetime.datetime(2020, 11, 1, 4, 0), 91, 'Y', 5054, <cx_Orac
le.LOB object at 0x00000237AE895710>, 'rc_patch', datetime.datetime(2020, 11, 5, 19, 19, 9))

这在较大的查询中运行速度非常慢。我不知道怎样才能让这一切变得更好。

首先,正如Chris所建议的,找出减速发生的地方。根据你的发现,我有几个建议:

(1( 避免获取LOB值,因为这些值需要额外的往返行程来获取数据,从而减慢了过程。你可以在这里看到一个例子。

(2( 如果前面的建议不够,您还可以考虑简单地独立获取三(四?(个查询,并将它们放在Python中(通过使用dicts(。这样就不需要多次获取顶级行,然后再删除重复行。

最新更新