Как избежать дублирования данных в базе данных PostgreSQL в Python - PullRequest
2 голосов
/ 10 марта 2010

Я работаю над PostgreSQL и psycopg2. Попытка чтобы получить данные фида, которые обновляются каждые 10 минут и сохранить это содержимое каналов в базе данных PostgreSQL. Моя цель заключается в получении и распечатать эти данные из этой таблицы. Но возникающая проблема, так как дубликаты данных также сохраняются в базе данных каждый раз, когда я запускаю этот скрипт из-за операции вставки в таблицу.

Чтобы избежать этой проблемы, я установил ограничение первичного ключа для столбца location_title в таблице Locations-musiq1, где я намерен хранить данные фида. Но возникла ошибка.

Вот мой код:

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()

Моя ошибка после изменения столбца таблицы location_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 ]

2 голосов
/ 10 марта 2010

Вы можете попробовать что-то вроде этого:

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))
2 голосов
/ 10 марта 2010

Ваш код имеет только INSERT, так что, как вы думаете, произойдет, когда вы получите те же данные во второй раз?

Обновление не выполняется, поскольку вы пытаетесь вставить строку, значение поля которой идентично значению поля, которое уже существует в столбце с уникальным ограничением.

Вам нужно либо сопоставить записи из ленты новостей с вашей таблицей и соответственно ВСТАВИТЬ, ОБНОВИТЬ, УДАЛИТЬ. Где это уместно, определяется данными фида и причинами вашей синхронизации. Или вы очищаете свой стол и каждый раз заполняете его из фида.

Чего вы пытаетесь достичь?

1 голос
/ 10 марта 2010

Рахман. Вы задаете второй вопрос в своем комментарии, который, вероятно, следует вместо этого сделать своим собственным вопросом.

В любом случае, чтобы вернуть результаты в указанном порядке, вам нужно упорядочить предложение. Я не вижу столбец отметки времени здесь, но я предполагаю, что данные вашего канала отформатированы в XML. Вы можете заказать по некоторому выражению xpath. Но если вы просто хотите, чтобы они были в том порядке, в котором они были вставлены, вы можете отсортировать их по скрытому системному столбцу xmin, который является идентификатором транзакции операции вставки.

См. Документацию по системным столбцам .

...