我有一张桌子
id | 朋友们 |
---|---|
1 | 空 |
2 | 空 |
3 | [1, 4] |
4 | [1, 2] |
我的任务是建立用户朋友的所有联系
如果 Friends 为 NULL,那么我们将遍历所有其他 ID。 并寻找谁有这个ID作为好友。
ID 为 1 时为 NULL。 我们使用该脚本来查找谁的朋友中有 1。 它的 ID 编号为 3 和 4。 因此,记住 3 和 4,在完成所有操作后,将此数组保存到第一个数组中。 每行依此类推。
所以,我必须确定哪些ID与我要查找的ID是好友。 确定后,我将得到一个数组,与我编写的数组相同,而不是 NULL。
所以我应该得到:
id | 朋友们 |
---|---|
1 | [3, 4] |
2 | 4 |
3 | [1, 4] |
4 | [1, 2] |
但是如果不为NULL,还是需要遍历所有用户,记录是否有变化
ID 4 有一个像这样的列表 [1, 2]。 但 ID 3 拥有用户 4 ([1, 4])。 所以我将 4 添加到现有列表中。
原来是这样的: [1, 2]
应该是这样的: [1,2,3]
(重要,你必须执行.sort())
我做了什么。
for row in cursor:
id = row[0]
friends = row[1]
print(id, friends)
if friends == None:
new_friends = []
for row in cursor:
fr_id = row[0]
str_fr_friends = row[1]
if str_fr_friends != None:
fr_id = row[0]
str_fr_friends = row[1]
fr_friends = json.loads(str_fr_friends)
# print(fr_id, fr_friends)
if fr_id not in new_friends:
if id in fr_friends:
new_friends.append(fr_id)
print(id, new_friends)
# print(fr_id, fr_friends)
new_friends = json.dumps(new_friends)
if new_friends != []:
cursor.execute("UPDATE Users SET friends = ? WHERE id = ?", (new_friends, id))
我决定从friends为NULL的情况开始处理。
我的问题是代码只编辑第一行。如果我再次运行它,它会转到第二行。
我添加了一个部分来处理朋友不为 NULL 的情况,但这让事情变得更糟。
问题:如何让脚本编辑每一行?
我的数据库有 850,000,000 行,所以我正在逐行读取它。也许我应该使用不同的方式来读取它,但是绝对不可能将其完全加载到文件中
由于大量记录和表范围的聚合操作,使用查询可能是最有效的,而不是通过 Python 将大部分/全部记录加载到内存中。该查询扫描每一行,并执行两个操作:
friends
是 null
,则它会查找表中在其 id
数组中具有 null
好友 id
的所有其他 friends
,并聚合结果friends
数组将通过union all
与在其id
数组中包含原始id
的所有其他friends
合并select p.id, case when p.friends is null then (select json_group_array(p1.id)
from people p1 where exists (select 1 from json_each(p1.friends) v where v.value = p.id))
else (select json_group_array(v1.pid) from (select p1.id pid from people p1
where exists (select 1 from json_each(p1.friends) v where v.value = p.id)
union all
select v.value pid from json_each(p.friends) v) v1) end
from people p