Ошибка, возникающая при использовании to_sql для записи pandas df в mysql

#python #pandas #sqlalchemy #pymysql #praw

#python #pandas #sqlalchemy #pymysql #praw

Вопрос:

Я очищаю reddit с помощью praw и сохраняю записи в pandas df. Использование комбинации sqlalchemy и pymysql для подключения к моей базе данных AWS RDS и to_sql для добавления записей в существующую таблицу. Кажется, все работает нормально, пока я не нажму на метод to_sql. Он выдает следующие ошибки, и я не совсем уверен, куда идти дальше. Любая помощь или предложения были бы потрясающими!

 engine = sqlalchemy.create_engine('mysql pymysql://username:password@database...rds.amazonaws.com:3306/socialdata')
df_comment = pd.DataFrame(comment_table)

df_comment.to_sql(name='reddit_comments', con=engine, index=False, if_exists='append')
  
 Traceback (most recent call last):
  File "/Users/ty/Desktop/Python/reddit_scraper.py", line 121, in <module>
    df_comment.to_sql(name='reddit_comments', con=engine, index=False, if_exists='append')
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pandas/core/generic.py", line 2605, in to_sql
    sql.to_sql(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pandas/io/sql.py", line 589, in to_sql
    pandas_sql.to_sql(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pandas/io/sql.py", line 1398, in to_sql
    table.insert(chunksize, method=method)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pandas/io/sql.py", line 830, in insert
    exec_insert(conn, keys, chunk_iter)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pandas/io/sql.py", line 747, in _execute_insert
    conn.execute(self.table.insert(), data)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1011, in execute
    return meth(self, multiparams, params)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/sql/elements.py", line 298, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1124, in _execute_clauseelement
    ret = self._execute_context(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1316, in _execute_context
    self._handle_dbapi_exception(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1514, in _handle_dbapi_exception
    util.raise_(exc_info[1], with_traceback=exc_info[2])
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
    raise exception
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1256, in _execute_context
    self.dialect.do_executemany(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/mysqldb.py", line 148, in do_executemany
    rowcount = cursor.executemany(statement, parameters)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/cursors.py", line 188, in executemany
    return self._do_execute_many(q_prefix, q_values, q_postfix, args,
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/cursors.py", line 206, in _do_execute_many
    v = values % escape(next(args), conn)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/cursors.py", line 120, in _escape_args
    return {key: conn.literal(val) for (key, val) in args.items()}
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/cursors.py", line 120, in <dictcomp>
    return {key: conn.literal(val) for (key, val) in args.items()}
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/connections.py", line 469, in literal
    return self.escape(obj, self.encoders)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/connections.py", line 462, in escape
    return converters.escape_item(obj, self.charset, mapping=mapping)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/converters.py", line 27, in escape_item
    val = encoder(val, mapping)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/converters.py", line 123, in escape_unicode
    return u"'%s'" % _escape_unicode(value)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pymysql/converters.py", line 78, in _escape_unicode
    return value.translate(_escape_table)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/praw/models/reddit/base.py", line 35, in __getattr__
    return getattr(self, attribute)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/praw/models/reddit/base.py", line 36, in __getattr__
    raise AttributeError(
AttributeError: 'Redditor' object has no attribute 'translate'
  

Ответ №1:

Один из столбцов в вашем фрейме данных содержит пользовательский объект «Redditor», который не сопоставляется с соответствующим типом данных SQL. pymysql вызывает функцию translate объекта, когда это не что-то очевидное, например, int float или string

Если Redditor — это просто объект-оболочка для хранилища имен пользователей и других метаданных, то вы можете сделать что-то вроде переназначения этого столбца в строковое / числовое представление объекта Redditor. Если это объект, который вы определили, вы можете добавить функцию translate() в определение класса Redditor, чтобы вернуть соответствующее значение. Например, если Redditor.id содержит значение, которое вы хотите сохранить в столбце :-

 class Redditor():
  def translate(self):
    # Change self.id with the value you care about
    return self.id 
  

или в pandas перед сохранением

df[REDDITOR_COLUMN] = df[REDDITOR_COLUMN].apply(lambda x: x.id)

Комментарии:

1. эй, ты абсолютно прав, я на секунду опередил себя, не проверив, отредактировав сообщение соответствующим образом, спасибо!