【问题标题】:Pandas: milliseconds dropped when writing data to MySQLPandas:将数据写入 MySQL 时的毫秒数下降
【发布时间】:2019-04-11 23:42:42
【问题描述】:

我正在尝试将带有毫秒时间戳的 DataFrame 获取到 MySQL 数据库中。但是,这样做时,毫秒部分似乎被丢弃了。我创建了一个工作示例来展示发生了什么:

import pandas as pd
from sqlalchemy import create_engine # database connection

#Generate date_time with millisecond resolution and price column
df=pd.DataFrame({'date_time' : pd.date_range('1/1/2000 09:00:00', freq="5ms",periods=100),'price' : np.random.random_sample(100)})

#Connect with an empty MySQL database (which I simply created using CREATE DATABASE trading_db;)
disk_engine = create_engine("mysql+mysqldb://root:"+'MYPASSWORD'+"@localhost/trading_db")

#Dataframe to SQL in a Table called trading_data
df.to_sql('trading_data', disk_engine, if_exists='replace',index=False)

#When I read this back from MySQL, the milliseconds seem to dissapear
df_sql = pd.read_sql_query('SELECT *'
                   'FROM trading_data '
                   'LIMIT 20', disk_engine)

比较在pandas 中创建的DataFrame 的日期时间与从MySQL 加载的日期时间:

df.head()

    date_time                   price
0   2000-01-01 09:00:00         0.371986
1   2000-01-01 09:00:00.005000  0.625551
2   2000-01-01 09:00:00.010000  0.631182
3   2000-01-01 09:00:00.015000  0.625316
4   2000-01-01 09:00:00.020000  0.522437

df_sql.head()

    date_time           price
0   2000-01-01 09:00:00 0.371986
1   2000-01-01 09:00:00 0.625551
2   2000-01-01 09:00:00 0.631182
3   2000-01-01 09:00:00 0.625316
4   2000-01-01 09:00:00 0.522437

您可以清楚地看到毫秒数减少了。有什么办法可以更改代码以保留毫秒部分?

编辑:我正在使用 MySQL Workbench 6.2 和 pandas 0.14.1

【问题讨论】:

  • 您需要在v5.6.4+ 上才能支持小数时间值。

标签: python mysql pandas


【解决方案1】:

如 cmets 中所述,您需要 MySQL v5.6.4+ 来支持小数秒 (docs)。
但是,正如docs 解释的那样,您需要将其明确指定为DATETIME(fsp),其中fsp 是小数秒精度,以便在日期时间列中启用此功能。

to_sql 中的默认设置是仅使用DateTime(默认的 sqlalchemy 日期时间类型)。但是,您可以使用 dtype 参数覆盖此默认值,并使用 MySQL specific DATETIME 类型指定精度:

In [11]: from sqlalchemy.dialects.mysql import DATETIME

In [12]: df.to_sql('trading_data', engine, dtype={'date_time': DATETIME(fsp=6)}, if_exists='replace', index=False)

In [13]: df_sql = pd.read_sql_query('SELECT * FROM trading_data', engine)

In [14]: df_sql.head()
Out[14]:
                   date_time     price
0        2000-01-01 09:00:00  0.152087
1 2000-01-01 09:00:00.005000  0.927375
2 2000-01-01 09:00:00.010000  0.540021
3 2000-01-01 09:00:00.015000  0.499529
4 2000-01-01 09:00:00.020000  0.797420

注意:dtype 参数需要 pandas 0.15.2+。

【讨论】:

  • 非常感谢您的回复!我更新到 pandas 0.16.1 并且使用 dtype 参数现在可以工作了。但是,我下载了最新版本的 MySQL Workbench (6.2) 和最新的 SQL 版本是 5.6.24(我绝对是 w.r.t. 数据库的初学者)。当我运行df.to_sql 并查看 MySQL Workbench 时,我看到确实有 6 个小数秒位置,但它们都为零。此外,当我随后使用pd.read_sql_query 时,我会返回所有“无”的日期时间列。你知道如何解决这个问题吗?谢谢!
  • 但是日期本身是正确的吗?此外,您使用的是哪个版本的 sqlalchemy,以及哪个驱动程序?正如 sqlalchemy 文档 (docs.sqlalchemy.org/en/improve_toc/dialects/…) 所说,并非所有驱动程序都支持小数秒。我使用了pymysql(所以但不知道它是否适用于例如MySQLdb
  • 我正在使用SQLAlchemy 1.0.4-1。但是,我刚刚安装了PyMySQL 0.6.6-1,现在一切正常(MySQLdb 没有)!
猜你喜欢
  • 2017-02-17
  • 1970-01-01
  • 2022-08-18
  • 2013-07-22
  • 2016-09-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
相关资源
最近更新 更多