簡體   English   中英

如何使用Python / psycopg2有效地更新大型PostgreSQL表中的列?

[英]How to efficiently UPDATE a column in a large PostgreSQL table using Python / psycopg2?

我有一張大桌子。 PostgreSQL 9.4數據庫中的1000萬行。 它看起來像這樣:

gid | number1 | random | result | ...
 1  |    2    |  NULL  |  NULL  | ...
 2  |   15    |  NULL  |  NULL  | ...
... |   ...   |   ...  |  ...   | ...

現在,我想random更新列,並將result作為number1的函數。 這意味着至少需要在數據庫外部的腳本中產生random 由於我的內存有限,我想知道如何使用psycopg2有效地做到這一點。 我相信我面臨兩個問題:如何在不使用過多RAM的情況下獲取數據,以及如何將其恢復到原來的狀態。 簡單方法如下所示:

curs.execute("""SELECT gid1, number1 FROM my_table;""")
data = curs.fetchall()

result = []
for i in data:
    result.append((create_random(i[1]), i[0]))
curs.executemany("""UPDATE my_table
                    SET random = %s
                    WHERE gid = %s;""",
                 results)
curs.execute("""UPDATE my_table
                SET result = number1 * random;""")

但是,這肯定會很快耗盡我的所有內存,並永遠需要進行UPDATE my_table

什么是更明智的策略? 該數據庫僅被訪問,可以被鎖定。 不幸的是,PostgreSQL隨機函數不適合我的情況。

unnest數據即可一次完成所有操作:

def create_random(i):
    return random() * i

curs.execute("select gid, number from t;")
data = curs.fetchall()

results = []
for i in data:
    results.append((create_random(i[1]), i[0]))

curs.execute("""
    update t
    set
        rnd = s.rnd,
        result = number * s.rnd
    from unnest(%s) s(rnd numeric, gid integer)
    where t.gid = s.gid;
""", (results,))

con.commit()

表t:

create table t (
    gid integer,
    number integer,
    rnd float,
    result float
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM