【问题标题】:Unable to store twitter responses into SQL Server无法将 Twitter 响应存储到 SQL Server
【发布时间】:2015-01-01 20:39:02
【问题描述】:

我正在尝试使用搜索 API 从 twitter 收集数据到带有 python 包 pyodbc 的 SQL 数据库中。

  • 我根据关键字执行此操作,并将输出存储在我在 SQL Server Express 2008 中设置的 MS SQL 数据库中

    1. 数据应先进入“TweetTemp”表
    2. 然后永久存储到“TweetBank”表中
    3. 最后在“TweetLog”表中保留一条记录。

我的程序能够连接到我的数据库,但是没有收到任何推文。我的“TweetLog”表中只返回了关键字和 runID。

其余表完全为空。 推文在 python 输出中返回,但在每条返回的推文上方都有一个意外错误

推文示例中显示的错误消息:

############### Unexpected error: <class 'pyodbc.DataError'> ##################################
        Tweet from @metallicalyrc Date: Tue Dec 30 12:03:04 +0000 2014
         September 27 1986: Cliff Burton dies in bus accident in Sweden. Truly a sad day. His legacy will live on forever. 

有谁知道如何解决这个问题,或者以前用 pyodbc 遇到过这个问题?我已经爬取了网络,但没有解决此错误消息的方法。似乎 pyodbc 可能没有正确处理数据,因此它没有被正确推送到 SQL 数据库,因为我看不到我的 sql 逻辑有问题。

这是我的代码:

import string, json, pprint
import urllib
import string, os, sys, subprocess, time

import pyodbc
import twitter

from genericpath import exists
from twitter.archiver import statuses
from collections import Counter
from lib2to3.btm_utils import tokens

CONSUMER_KEY = 'MY KEY'
CONSUMER_SECRET = 'MY SECRET'
OAUTH_TOKEN = 'MY OATH TOKEN'
OAUTH_TOKEN_SECRET = 'MUOATH TOKEN SECRET'
auth = twitter.oauth.OAuth(OAUTH_TOKEN, OAUTH_TOKEN_SECRET,
                           CONSUMER_KEY, CONSUMER_SECRET)
twitter_api = twitter.Twitter(auth=auth)
print twitter_api

conn = pyodbc.connect('DRIVER={SQL Server};SERVER=MYSERVERNAME;DATABASE=MYDBNAME;UID=sa;PWD=MYPASSWD')
cur = conn.cursor()
# connect to database and create a cursor to do some work

harvest_list = ['metallica', 'james hetfield', 'lars ulrich', 'kirk hammett', 'rob trujillo', 'jason newsted', 'cliff burton']
# harvest list separated in the database by keyword

cur.execute("select max(isnull(batchid,0)) from tweetlog")
batch_id_cur = cur.fetchall()
# updated 3-8-2012
if batch_id_cur[0][0] is None:
    batch_id = 0
else:
    batch_id = batch_id_cur[0][0]+1
# grabbing the last "batch id", if it exists in order to make log entries that make SOME sense

for tweet_keyword in harvest_list: # for each keyword, do this

    cur.execute("""delete from tweetbanktemp where tweet_keyword = '"""+str(tweet_keyword)+"""'""")
conn.commit()
# whack the temp table in case didn't exit cleanly

search_results = twitter_api.search.tweets(q=tweet_keyword, count =100)
# search for the current keyword

for tweet in search_results['statuses']:
        # some me the tweet, jerry!
        print "        Tweet from @%s Date: %s" % (tweet['user']['screen_name'].encode('utf-8'),tweet['created_at'])
        print "        ",tweet['text'].encode('utf-8'),"\n"

        try:
                # try to to put each tweet in the temp table for now
                cur.execute("""insert into TweetBankTemp (tweet_id, tweet_datetime, tweet_keyword, tweet, tweeter, lang)
                                         values ('"""+str(tweet['id_str'].encode('utf-8').replace("'","''").replace(';',''))+"""',
                                                 '"""+str(tweet['created_at'].encode('utf-8'))+"""',
                                                 '"""+str(tweet_keyword)+"""',
                                                 '"""+str(tweet['text'].encode('utf-8').replace("'","''").replace(';',''))+"""',
                                                 '"""+str(tweet['user']['screen_name'].encode('utf-8').replace("'","''").replace(';',''))+"""',
                                                 '"""+str(tweet['metadata']['iso_language_code'].encode('utf-8').replace("'","''").replace(';',''))+"""'
                                         ) """)
        except:
                print "############### Unexpected error:", sys.exc_info()[0], "##################################"
# backup in case something bad happens all the tweets arnt lost

        cur.execute("""insert into tweetbank (tweet_id, tweet_datetime, tweet_keyword, tweet, tweeter, lang)
         select * from tweetbanktemp where tweet_id NOT in
         (select distinct tweet_id from tweetbank)""")
# take all the tweets DIDNT already have and put them in the REAL tweet table

        cur.execute("""delete from tweetbanktemp where tweet_keyword = '"""+str(tweet_keyword)+"""'""")
# take all THESE out of the temp table to not interfere with the next keyword

        cur.execute("""insert into tweetlog (BatchId, keyword, RunDate, HarvestedThisRun, TotalHarvested) values
         (
         '"""+str(batch_id)+"""',
         '"""+str(tweet_keyword)+"""',
         getdate(),
         ((select count(*) from tweetbank where tweet_keyword = '"""+str(tweet_keyword)+"""')-(select top 1 isnull(TotalHarvested,0) from tweetlog where keyword = '"""+str(tweet_keyword)+"""' order by RunDate desc)),
         (select count(*) from tweetbank where tweet_keyword = '"""+str(tweet_keyword)+"""')
         )""")
# add a record to the log table saying what happened

        conn.commit()
        # finish

【问题讨论】:

    标签: python sql-server twitter pyodbc


    【解决方案1】:

    您必须使用 SQL 服务器吗?如果必须使用它,为什么要使用古老且有问题的 ODBC?基于 TDS 会不会更好,例如 pymssql?

    我建议切换到 pymssql 并有一个测试脚本,该脚本从命令行接收假推文并将其放入数据库。 (您可以使用另一个脚本来删除所有测试推文)。一旦这是可靠的,你的管道的其余部分应该没问题。

    【讨论】:

    • 你好安德鲁。我也一直在尝试使用 pymssql,但我什至无法让它连接到我的 SQL 数据库,因此使用了 pyodbc。这是我尝试使用不同参数失败的连接字符串:“conn = pymssql.connect(server='MYSERVERNAME', host='localhost', user='sa', password='MYPASSWD', database='MYDBNAME ')"
    • 在不知道你的具体服务器的情况下,我无法提供连接参数;) 你是否仅限于使用 mssql?
    • 您需要哪些具体细节?在某种意义上是的。我之前尝试过使用 MYSQL,但遇到了一些数据类型错误,甚至无法连接到服务器。使用 mssql 是我取得的最大进步。
    • 我已经设法通过添加端口号参数为 pymssql 提供正确的连接字符串。但是,在返回的每条推文上方产生的错误现在是“pymssql.Operational Error”
    【解决方案2】:

    tweet_datetime 是 DateTime 列吗? 如果是,则问题不在于连接,而在于您的 SQL

    尝试打印出您通过 ODBC 发送的 SQL 文本,它可能看起来像这样:

    insert into TweetBankTemp (tweet_id, tweet_datetime, tweet_keyword, tweet, tweeter, lang)
                                         values ('SomeTweetID',
                                                 'Tue Dec 30 12:03:04 +0000 2014',
                                                 'SomeTweetKeyword',
                                                 'September 27 1986: Cliff Burton dies in bus accident in Sweden. Truly a sad day. His legacy will live on forever. ',
                                                 '@metallicalyrc',
                                                 'en-us'
                                         ) 
    

    如果您在 SSMS 中运行它,您将收到日期转换错误。 SQL Server 不知道如何将 Tue Dec 30 12:03:04 +0000 2014 转换为日期。

    尝试打印查询并查看是否是问题所在。如果是,您需要添加一些逻辑来将您的日期转换为 SQL Server 可以理解的格式(我建议 yyyy-mm-dd hh:mm:ss)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      相关资源
      最近更新 更多