2010-03-10 5 views
2

Je travaille sur PostgreSQL et psycopg2. Essayer pour obtenir des données de flux qui est mis à jour tous les 10 minutes et conserver ce contenu dans la base de données PostgreSQL. Mon objectif est de récupérer et d'imprimer ces données à partir de cette table. Mais face au problème que les données en double sont également stockées dans la base de données chaque fois que je cours ce script en raison de l'opération d'insertion sur la table.Éviter les données dupliquées dans la base de données PostgreSQL en Python

Pour sortir de ce problème, j'ai fait la contrainte de clé primaire de la colonne location_title dans la table Locations-musiq1 où j'ai l'intention de stocker mes données de flux.Mais face à l'erreur.

Voici mon code:

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

Mon erreur après avoir changé "locations_musiq1" tables colonne "location_title" comme clé primaire est:

 
    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" 

Quelqu'un peut-il avoir une idée de sortir de cette problème? .. Merci d'avance ..

Répondre

2

Vous pouvez essayer quelque chose comme ceci:

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)) 
+0

Merci pour la réponse .. Mais je face à problème comme les données d'alimentation ne sont pas l'impression en série, ils supposés imprimer .. Comme ils montrent des données (partie de mes données de sortie de script):! X était à Londres (à 2010-03-10 14: 46: 35.0) X était à Londres (au 2010-03-10 15: 30: 35.0) X était à Londres (à 2010-03-10 15: 19: 35.0) X était à Londres (au 2010-03-10 15: 08: 35,0 X était à Londres (au 2010-03-10 14: 57: 38,0) X était à Londres (au 2010-03-10 14: 24: 35.0) Donc, vous voyez que tous ceux qui ne sont pas apparaissent en série, mais ils supposent apparaître en série! Avez-vous une idée à ce sujet pour obtenir tout cela en série ??!? –

+0

Une fois que vous les avez insérés dans la base de données, utilisez simplement un select de l'ordre emplacements_musiq1 de mydatefield asc' (ou desc) – ChristopheD

2

Votre code a seulement INSERT, alors que pensez-vous qu'il va se passer quand vous récupérez les mêmes données pour une seconde ti moi?

Votre mise à jour échoue car vous essayez d'insérer une ligne qui a une valeur de champ identique à celle qui existe déjà dans une colonne avec une contrainte unique.

Vous devez soit faire correspondre les entrées du flux à votre table et INSERT, UPDATE, DELETE selon le cas. Le cas échéant est défini par les données de flux et les raisons de votre synchronisation. Ou vous videz votre table et la remplissez à chaque fois.

Qu'essayez-vous d'accomplir?

1

Rahman. Dans votre commentaire, vous posez une deuxième question qui devrait probablement faire l'objet de sa propre question.

De toute façon, pour renvoyer les résultats dans un ordre spécifié, vous avez besoin d'une clause order by. Je ne vois pas de colonne d'horodatage ici, mais je suppose que vos données de flux sont formatées en XML. Vous pouvez commander par une expression xpath. Mais si vous les voulez simplement dans l'ordre dans lequel ils ont été insérés, vous pouvez trier par la colonne système cachée xmin, qui est l'identifiant de transaction de l'opération d'insertion.

Voir la documentation au system columns.

Questions connexes