在Python中避免PostgreSQL数据库中的重复数据
我正在使用PostgreSQL和psycopg2,想要获取每10分钟更新一次的数据,并把这些数据存储在PostgreSQL数据库里。我的目标是从这个表中提取并打印这些数据。
但是每次运行这个脚本时,由于在表中插入数据,数据库里总是会存储重复的数据,这让我很困扰。
为了避免这个问题,我在表Locations-musiq1
的location_title
列上设置了主键约束,打算用来存储我的数据。但我遇到了错误。
这是我的代码:
import psycopg2
import sys
import feedparser
import codecs
import psycopg2.extensions
# Parsing data from Geofeed location feeds
data = feedparser.parse("some URL")
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
try:
conn=psycopg2.connect("dbname='name' user='postgres' host='localhost' password='abcds'")
conn.set_client_encoding('UNICODE')
except:
print "I am unable to connect to the database, exiting."
sys.exit()
cur=conn.cursor()
for i in range(len(data['entries'])):
cur.execute("INSERT INTO locations_musiq1(location, location_title) VALUES (%s, %s)", (data.entries[i].title,data.entries[i].summary))
conn.commit()
cur.execute("SELECT * FROM locations_musiq1;")
cur.fetchone()
for row in cur:
print ' '.join(row[1:])
cur.close()
conn.close()
在把"locations_musiq1"表的"location_title"列设置为主键后,我遇到的错误是:
Traceback (most recent call last): File "F:\JavaWorkspace\Test\src\postgr_example.py", line 28, in cur.execute("INSERT INTO locations_musiq1(location, location_title) VALUES (%s, %s)", (data.entries[i].title,data.entries[i].summary)) psycopg2.IntegrityError: duplicate key value violates unique constraint "locations_musiq1_pkey"
有没有人能给我一些建议,帮我解决这个问题呢?谢谢!
3 个回答
1
Rahman,你在评论里问的第二个问题,可能应该单独提出来问。
无论如何,如果你想按照特定的顺序返回结果,就需要使用“order by”这个语句。我在这里没有看到时间戳的列,但我猜你的数据是用XML格式的。你可以根据某个xpath表达式来排序。不过,如果你只是想按照数据插入的顺序来排列,可以使用一个隐藏的系统列xmin,它是插入操作的事务ID。
可以查看关于系统列的文档。
2
你的代码里只有 INSERT
,那么你觉得当你第二次获取相同的数据时会发生什么呢?
你的更新失败是因为你试图插入一行数据,而这行数据的某个字段值和已经存在的某行数据的字段值是一样的,而这个字段是有唯一性限制的。
你需要根据数据源中的内容来匹配你表格里的条目,然后根据需要进行插入、更新或删除。这里的“需要”是根据数据源的数据和你同步的目的来决定的。或者,你也可以每次都清空你的表格,然后从数据源重新填充数据。
你想要达到什么目的呢?
2
你可以试试这样的做法:
cur.execute("""
INSERT INTO locations_musiq1(location, location_title)
SELECT %s, %s WHERE NOT EXISTS
(SELECT location_title FROM locations_musiq1 WHERE location_title=%s);
""", (data.entries[i].title, data.entries[i].summary, data.entries[i].summary))