2016-06-17 14 views
0

Ich kann Daten aus Tweets abrufen und in der MySQL-Tabelle speichern. aber das Problem ist manchmal ein Tweet hat doppelte Tweets mit dem gleichen Wert. Ich möchte wissen, ob es möglich ist, das Einfügen in Tabelle zu stoppen, wenn doppelte Werte mit Flask-SQLAlchemy erkannt werden.Stoppen Sie das Einfügen in die Tabelle, wenn der doppelte Wert erkannt wurde Flask SQLAlchemy

from tweepy import Stream 
from tweepy import OAuthHandler 
from tweepy.streaming import StreamListener 
from flask_sqlalchemy import SQLAlchemy 
from models import TrainingTweets, db 
import mysql.connector 
import json 
import tweepy 
from tweepy.api import API 

#consumer key, consumer secret, access token, access secret. 
ckey="" 
csecret="" 
atoken="" 
asecret="" 

auth = OAuthHandler(ckey, csecret) 
auth.set_access_token(atoken, asecret) 

api = tweepy.API(auth) 


class listener(StreamListener): 

    def __init__(self, api=None): 
     self.api = api or API() 
     self.n = 0 
     self.m = 50 

    def on_data(self, data): 
     all_data = json.loads(data) 
     self.n = self.n+1 
     if self.n <= self.m: 
      tweet = all_data["text"] 
      username = all_data["user"]["screen_name"] 
      label = "1" 
      ttweets = TrainingTweets(label_id=label, tweet_username=username, tweet=tweet) 
      db.session.add(ttweets) 
      checkedtweet = TrainingTweets.query.filter(ttweets.tweet).all() 
      if not checkedtweet: 
       db.session.commit() 
       print((username, tweet)) 
       return True 
      else: 
       print("Duplicate entry detected!") 
       return False 
     else: 
      print("Successfully stored ", self.m, " tweets into database") 
      return False 

    def on_error(self, status): 
     print(status) 

auth = OAuthHandler(ckey, csecret) 
auth.set_access_token(atoken, asecret) 

twitterStream = Stream(auth, listener()) 
twitterStream.filter(track=["health"], languages=["en"], follow="") 

hier ist mein model.py:

class TrainingTweets(db.Model): 
    tweet_id = db.Column(db.Integer, primary_key=True) 
    tweet_username = db.Column(db.String(50)) 
    tweet = db.Column(db.String(191)) 
    slug = db.Column(db.String(191), unique=False) 
    created_date = db.Column(db.DateTime, default=datetime.datetime.now) 
    label_id = db.Column(db.Integer, db.ForeignKey('label.label_id')) 

    def __init__(self, *args, **kwargs): 
     super(TrainingTweets, self).__init__(*args, **kwargs) # Call parent constructor. 
     self.generate_slug() 

    def generate_slug(self): 
     self.slug = '' 
     if self.tweet: 
      self.slug = slugify(self.tweet) 
+0

Sie tun bedeuten wie in "stop the presses" und der ganze Zuhörer stoppt, oder "ignoriere diesen IntegrityError"? –

+0

ist es möglich, das Einfügen zu überspringen, wenn es doppelt vorhanden ist, und ein neues einzufügen? das ist es, was ich eigentlich machen möchte. Aber wenn das nicht möglich ist, dann möchte ich den ganzen Listener stoppen, wenn es ein Duplikat gibt. – Indra

+0

Haben Sie einen eindeutigen Index für Ihren Tisch eingerichtet? IOW Was ist "TrainingTweets"? –

Antwort

1

Ihr Modell eindeutige Indizes für einige Kriterien haben sollten Duplikate auf entfernen. Column s sind standardmäßig nicht eindeutig, was Sie zu übernehmen scheinen (unique=False in einer Spalte und die Kommentare). Sie sollten entweder anstelle eines automatisch inkrementierenden Ersatzschlüssels einen "natürlichen" Schlüssel wie die von Twitter bereitgestellte ID verwenden oder die Textspalte tweet eindeutig machen.

Wenn Sie die Einzigartigkeit Anforderungen festgelegt haben, und wenn Sie es wünschen IntegrityError s zu ignorieren und weitermachen, wickeln Sie Ihre Einsätze in Transaktionen (oder das implizite Verhalten verwenden) und begehen oder entsprechend Rollback:

from sqlalchemy.exc import IntegrityError 

class listener(StreamListener): 

    def on_data(self, data): 
     all_data = json.loads(data) 
     tweet_id = all_data["id_str"] 
     tweet_text = all_data["text"] 
     tweet_username = all_data["user"]["screen_name"] 
     label = 1 
     ttweets = TrainingTweets(label_id=label, 
           tweet_username=tweet_username, 
           tweet=tweet_text) 

     try: 
      db.session.add(ttweets) 
      db.session.commit() 
      print((username, tweet)) 
      # Increment the counter here, as we've truly successfully 
      # stored a tweet. 
      self.n += 1 

     except IntegrityError: 
      db.session.rollback() 
      # Don't stop the stream, just ignore the duplicate. 
      print("Duplicate entry detected!")  

     if self.n >= self.m: 
      print("Successfully stored", self.m, "tweets into database") 
      # Cross the... stop the stream. 
      return False 
     else: 
      # Keep the stream going. 
      return True 
+0

danke! @Iija das ist was ich will. :) Jetzt funktioniert es wie Charme! : D – Indra

+0

Ah, gut, dass es funktioniert. Ihr Modell war so, dass ich ein Vorwort in der Antwort über Einzigartigkeit geschrieben habe, aber es scheint, dass Sie es nicht brauchen. –

+0

Nun, ich habe bemerkt, was Sie oben beschreiben, also vielen Dank. :) – Indra