如何仅添加那些尚未添加到数据库的记录

时间:2019-01-23 13:32:21

标签: python postgresql

我正在使用Postgresql。我的代码如下:

vehicles = get_vehicle_references()
for vehicle in vehicles:
    insert_into_db(vehicle[0], vehicle[1])

get_vehicle_references()如下:

def get_vehicle_references():
    conn = db_connection()
    cur = conn.cursor()
    try:
        s = "SELECT reference, reference_url FROM vehicles v WHERE NOT EXISTS (select reference from daily_run_vehicle rv WHERE handled = %s AND retries < %s  AND rv.timestamp::timestamp::date = %s AND v.reference=reference) ORDER BY id DESC"
        cur.execute(s, (False, 5, today))
        return cur.fetchall()
    except Exception as e:
        capture_error(str(e))
    conn.close()

因此该函数中的查询如下:

SELECT reference, reference_url
FROM vehicles v
WHERE NOT EXISTS
    (select reference from daily_run_vehicle rv
     WHERE handled = False
         AND retries < 5
         AND rv.timestamp::timestamp::date = str(date.today())
         AND v.reference=reference)
ORDER BY id DESC

我得到了referencereference_url,然后将它们插入数据库中。

我每天重复500次以上。我想要的如下:

  • 首次执行时,如果referencevehicles中的daily_run_vehicle的{​​{1}}字段= handled和{{1} },我想在数据库中插入False

  • 当同一天再次查询该查询时,我想检查是否 retries < 5中的reference的{​​{1}}字段= reference,并且当天daily_run_vehicle已添加到handled表中。 如果它已经被添加,我想跳过该记录。

我在这里迷路了。有人可以帮我吗?

1 个答案:

答案 0 :(得分:3)

在要向其中插入记录的表中添加UNIQUE INDEX

CREATE UNIQUE INDEX yourtable_idx on yourtable (date, reference, reference_url);

请注意,date是唯一索引的一部分。因此,每个唯一的(date, reference, reference_url)元组只能插入一次。

然后,您可以使用SQL将记录插入yourtable中:

INSERT INTO table (date, reference, reference_url)
VALUES (%s, %s, %s)
ON CONFLICT (date, reference, reference_url) DO NOTHING

ON CONFLICT ... DO NOTHING子句告诉Postgresql,如果 (date, reference, reference_url)元组已经在yourtable中。

一旦使用唯一索引设置了Postgresql表,就可以不受惩罚地插入,而不必担心在Python代码中创建重复项。在数据库级别执行此操作比在应用程序级别进行一致的编码要容易和可靠得多。