#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. эй, ты абсолютно прав, я на секунду опередил себя, не проверив, отредактировав сообщение соответствующим образом, спасибо!