未从 Python 正确导入 SQL 数据库的日期
Dates not importing to SQL database correctly from Python
我有以下(a 的子集)Pandas 数据框,我正在尝试将其上传到 MySQL 数据库:
以下是使用 info() 函数的数据的详细信息:
为了添加上下文,我之前使用以下代码将 tourn_date
和 date
列都转换为日期时间格式:
pd.to_datetime(all_data['tourn_date']).dt.date
最后,这是我用来将数据导入 MySQL 数据库的代码:
for index, row in all_data.iterrows():
inserts = [row.tourn_id, row.year, row.round_num, row.tourn_date, row.date]
cursor.execute("""INSERT INTO AllPlayerStats
(TourneyID, Year, RoundNum, TourneyDate, TDate)
values(%s,%s,%s,%s,%s)""", inserts)
db.commit()
cursor.close()
然而,当我 运行 这样做时,一些日期(如上面显示的日期)在数据库中显示为 NULL(见下文),尽管其他比赛工作正常并且格式数据库中的 TourneyDate
和 Date
列是日期类型。在某些情况下,tourn_date
可以正确上传,但 date
不能。
有没有办法解决这个问题并了解为什么会发生这种情况?我对这里发生的事情感到很困惑。
Python 声称日期是数据类型对象,您需要先将它们转换为日期类型。有关如何投射为日期的信息,请参见此处:
https://www.w3schools.com/sql/func_mysql_cast.asp
此外,请确保您要插入的 MySQL 列也具有正确的数据类型格式。大多数没有意义的问题通常是数据类型问题,很容易将 x = 1 与 y = "1" 进行比较并且不理解为什么 x 不等于 y。
更新 - 出现了第二个答案,概念是一样的,我想区别在于你是想用 Python 还是用 MySQL.
考虑将您的日期值转换为 StringDtype
(而非 object
)或不带 dt.date
属性的 datetime64
。 MySQL 可以将 Python 日期时间映射到它的 date
类型(即减去时间分量)。还考虑来自 DataFrame.to_numpy()
.
的 executemany
请注意:astype("string")
呈现 StringDtype
并且不同于呈现 object
类型的 astype(str)
或 astype("str")
。
sql = """INSERT INTO AllPlayerStats (TourneyID, Year, RoundNum, TourneyDate, TDate)
VALUES (%s, %s, %s, %s, %s)"""
# StringDtype
all_data["tourn_date"], all_data["date"] = (
all_data["tourn_date"].astype("string"),
all_data["date"].astype("string")
)
# datetime
all_data["tourn_date"], all_data["date"] = (
pd.to_datetime(all_data["tourn_date"]),
pd.to_datetime(all_data["date"])
)
vals = all_data[["tourn_id", "year", "round_num", "tourn_date", "date"]].to_numpy()
cursor.executemany(sql, vals)
db.commit()
cursor.close()
我有以下(a 的子集)Pandas 数据框,我正在尝试将其上传到 MySQL 数据库:
以下是使用 info() 函数的数据的详细信息:
为了添加上下文,我之前使用以下代码将 tourn_date
和 date
列都转换为日期时间格式:
pd.to_datetime(all_data['tourn_date']).dt.date
最后,这是我用来将数据导入 MySQL 数据库的代码:
for index, row in all_data.iterrows():
inserts = [row.tourn_id, row.year, row.round_num, row.tourn_date, row.date]
cursor.execute("""INSERT INTO AllPlayerStats
(TourneyID, Year, RoundNum, TourneyDate, TDate)
values(%s,%s,%s,%s,%s)""", inserts)
db.commit()
cursor.close()
然而,当我 运行 这样做时,一些日期(如上面显示的日期)在数据库中显示为 NULL(见下文),尽管其他比赛工作正常并且格式数据库中的 TourneyDate
和 Date
列是日期类型。在某些情况下,tourn_date
可以正确上传,但 date
不能。
有没有办法解决这个问题并了解为什么会发生这种情况?我对这里发生的事情感到很困惑。
Python 声称日期是数据类型对象,您需要先将它们转换为日期类型。有关如何投射为日期的信息,请参见此处:
https://www.w3schools.com/sql/func_mysql_cast.asp
此外,请确保您要插入的 MySQL 列也具有正确的数据类型格式。大多数没有意义的问题通常是数据类型问题,很容易将 x = 1 与 y = "1" 进行比较并且不理解为什么 x 不等于 y。
更新 - 出现了第二个答案,概念是一样的,我想区别在于你是想用 Python 还是用 MySQL.
考虑将您的日期值转换为 StringDtype
(而非 object
)或不带 dt.date
属性的 datetime64
。 MySQL 可以将 Python 日期时间映射到它的 date
类型(即减去时间分量)。还考虑来自 DataFrame.to_numpy()
.
executemany
请注意:astype("string")
呈现 StringDtype
并且不同于呈现 object
类型的 astype(str)
或 astype("str")
。
sql = """INSERT INTO AllPlayerStats (TourneyID, Year, RoundNum, TourneyDate, TDate)
VALUES (%s, %s, %s, %s, %s)"""
# StringDtype
all_data["tourn_date"], all_data["date"] = (
all_data["tourn_date"].astype("string"),
all_data["date"].astype("string")
)
# datetime
all_data["tourn_date"], all_data["date"] = (
pd.to_datetime(all_data["tourn_date"]),
pd.to_datetime(all_data["date"])
)
vals = all_data[["tourn_id", "year", "round_num", "tourn_date", "date"]].to_numpy()
cursor.executemany(sql, vals)
db.commit()
cursor.close()