Search code examples
pythonmysqltweepypymysql

TypeError: 'str' object is not callable when insert tweet data to mysql Python 3


This is my code to insert tweet data in MYSQL

import pymysql
import tweepy
import time
import json
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener
import pymysql.cursors

ckey= ''
csecret= ''
atoken=''
asecret=''

conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='admin1234', db='mysql')
cur = conn.cursor()

class listener(StreamListener):

 def on_data(self, data):
        all_data = json.loads(data)
        tweet = all_data["text"]
        a=0
        #username = all_data["user"]["screen_name"]

        cur.execute("INSERT INTO tweet (textt) VALUES (%s)" (tweet))
        print (tweet)
        return True

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

auth = OAuthHandler(ckey, csecret)
auth.set_access_token(atoken, asecret)
twitterStream = Stream(auth, listener())
twitterStream.filter(track = ["puasa"])

cur.close()
conn.close()

but i get error TypeError: 'str' object is not callable

traceback error

Traceback (most recent call last):
  File "collect-sql.py", line 40, in <module>
    twitterStream.filter(track = ["puasa"])
  File "/Users/amzar/anaconda3/lib/python3.6/site-packages/tweepy/streaming.py", line 450, in filter
    self._start(async)
  File "/Users/amzar/anaconda3/lib/python3.6/site-packages/tweepy/streaming.py", line 364, in _start
    self._run()
  File "/Users/amzar/anaconda3/lib/python3.6/site-packages/tweepy/streaming.py", line 297, in _run
    six.reraise(*exc_info)
  File "/Users/amzar/anaconda3/lib/python3.6/site-packages/six.py", line 693, in reraise
    raise value
  File "/Users/amzar/anaconda3/lib/python3.6/site-packages/tweepy/streaming.py", line 266, in _run
    self._read_loop(resp)
  File "/Users/amzar/anaconda3/lib/python3.6/site-packages/tweepy/streaming.py", line 327, in _read_loop
    self._data(next_status_obj)
  File "/Users/amzar/anaconda3/lib/python3.6/site-packages/tweepy/streaming.py", line 300, in _data
    if self.listener.on_data(data) is False:
  File "collect-sql.py", line 30, in on_data
    cur.execute("INSERT INTO tweet (textt) VALUES (%s)" (tweet))
TypeError: 'str' object is not callable

Solution

  • You need 2 extra commas:

    cur.execute("INSERT INTO tweet (textt) VALUES (%s)", (tweet,))
    

    The first separates the query string from the arguments, the second turns the value in brackets into the first element in a 1 element tuple (it actually would work if you just used a single string instead of a tuple, assuming you only have one argument, but this isn't officially supported from the look of things).

    But this error that you mentioned in the comments:

    UnicodeEncodeError: 'latin-1' codec can't encode character '\u201c' in position 97: ordinal not in range(256)
    

    means you are trying to interpret unicode text containing a character from the extended character set into latin-1.

    If the field is already internally defined (in your mysql database) as unicode, you may need to specify the character set to use when connecting e.g.:

    conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='admin1234', db='mysql', use_unicode=True, charset="utf8")
    

    If the field in mysql is not already something like utf-8 then I recommend you alter or otherwise redefine the database to use a unicode character se tfor this column.

    https://dev.mysql.com/doc/refman/8.0/en/charset-mysql.html