微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我有一张大桌子. Postgresql 9.4数据库中的1000万行.它看起来像这样:

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

现在,我想随机更新列,并将其结果作为number1的函数.这意味着至少需要在数据库外部的脚本中产生随机性.由于内存有限,我想知道如何使用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;""")

但是,这肯定会很快耗尽我的所有内存,并永远花费时间来更新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
);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐