2016-06-17 2 views
0

Я могу получить данные из твитов и хранить их в таблице MySQL. , но проблема в том, что у tweet есть дублированные твиты с одинаковым значением. Я хочу знать, можно ли прекратить вставку в таблицу при обнаружении дублирующегося значения с помощью Flask-SQLAlchemy.Остановить вставку в таблицу при обнаружении дублирующегося значения Колба 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="") 

вот мой 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

ли вам означает, что в «остановке прессов», и весь слушатель останавливается, или просто «игнорирует этот IntegrityError»? –

+0

Можно ли пропустить вставку, когда есть дубликат, и продолжить вставку нового? это то, что я хочу сделать на самом деле .. но если это невозможно сделать, тогда я хочу остановить весь слушатель, если есть дубликат. – Indra

+0

Вы создали уникальный индекс на своем столе? IOW, что такое «TrainingTweets»? –

ответ

1

Ваша модель должна иметь уникальные индексы для некоторых критериев для удаления дубликатов на. Column s по умолчанию не уникальны, что вы, кажется, принимаете (unique=False в колонке и комментариях). Вы должны либо вместо автоматического прироста суррогатного ключа использовать какой-то «естественный» ключ, такой как идентификатор, предоставленный твиттером, либо сделать текстовый столбец tweet уникальным.

Когда вы исправили требования к уникальности и если вы хотите игнорировать IntegrityError с и продолжайте идти, обернуть вставки в сделках (или использовать неявное поведение) и зафиксировать или откатить соответственно:

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

спасибо! @Iija это то, что я хочу. :) теперь он работает как шарм! : D – Indra

+0

А, хорошо, что он работает. Ваша модель была такой, что я написал предисловие в ответе о уникальности, но, похоже, вам это не нужно. –

+0

хорошо, я отметил то, что вы описали выше, так что спасибо вам большое. :) – Indra

Смежные вопросы