使用pandas.DataFrame.to_sql写入PostgreSQL时的时间戳类型不匹配问题
问题描述
我在用pandas.DataFrame.to_sql()往PostgreSQL表插入行时遇到了类型不匹配问题。
样例DataFrame:
index | m_date | ticker | close 0 | 1514937600 | AMD | 11.55
执行代码:
price_data.to_sql( 'prices', db_conn, if_exists='append', index=False, dtype={ 'close': sqlalchemy.types.FLOAT, 'm_date': sqlalchemy.types.TIMESTAMP, 'ticker': sqlalchemy.types.VARCHAR, } )
报错信息:
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DatatypeMismatch) column "m_date" is of type timestamp without time zone but expression is of type integer
LINE 1: ..._indicator, market_capitalization) VALUES (11.55, 1514937600...
^
HINT: You will need to rewrite or cast the expression.
尝试用.astype()转换类型时:
price_data.astype({'m_date': sqlalchemy.types.TIMESTAMP})
又报错:
TypeError: dtype '<class 'sqlalchemy.sql.sqltypes.TIMESTAMP'>' not understood
问题原因与解决方法
- 核心问题:
m_date列存的是Unix时间戳(整数),但PostgreSQL的timestamp类型需要日期时间对象,仅在to_sql的dtype里指定TIMESTAMP无法让pandas自动完成整数到日期类型的转换。 - 正确转换步骤:
- 先将DataFrame中的
m_date列从整数时间戳转为pandas的datetime类型:
注:如果是毫秒级时间戳,将price_data['m_date'] = pd.to_datetime(price_data['m_date'], unit='s')unit参数改为'ms'即可。 - 再执行
to_sql操作,此时dtype中的TIMESTAMP设置会正常生效,pandas会把datetime类型正确映射到PostgreSQL的timestamp类型。
- 先将DataFrame中的
.astype()失效原因:astype()仅支持pandas/numpy的 dtype(如'datetime64[ns]'),无法直接使用SQLAlchemy的类型,因此会触发类型不识别的错误。
内容的提问来源于stack exchange,提问作者DavidLojkasek
相关产品推荐
相关产品推荐

