[บันทึกกันลืม] วิธีแก้ปัญหาข้อมูลประเภท timedelta64[ns] ใน Pandas ไม่สามารถเขียนลงฐานข้อมูล field ที่เป็น Time ได้

เหตุ:

import pymysql
import pandas as pd
import sqlalchemy

import time
import datetime

conn = pymysql.connect(
        host="source.database.server",
        port=3306,
        user='username',
        password='password',
        database='databasename',
    )

sql="""
   SELECT *
   FROM   table1
"""
df1=pd.read_sql(sql,conn)
df1.dtypes

ผลคือ:

.
.
.
ref_visit_date                            object
ref_visit_time                   timedelta64[ns]
.
.
.

ซึ่ง ref_visit_time นั้น ใน MySQL/MariaDB ใช้ชนิดเป็น Time

เช่น 08:00:00 หมายถึง 8 นาฬิกา อะไรทำนองนั้น

ปัญหา:

อยู่ที่ตอนเอา Dataframe นี้ ไป Write ใส่อีก Table นึง

host="destination.database.server"
port=int(3306)
user='user'
password='password'
dbname='databasename'
db_string = f"mysql+pymysql://{user}:{password}@{host}:{port}/{dbname}"

destination_conn = sqlalchemy.create_engine(db_string)

df.to_sql('table2'
       , con=destination_conn
       , if_exists='append'
       , index=False
       , method='multi'
       , chunksize=10000)

ซึ่ง table2 นั้น มีโครงสร้างเหมือนกับ table1 เลย โดยเฉพาะ ref_visit_time มีชนิดเป็น Time เช่นกัน

แต่ถ้า run code นี้จะได้ Error/Warning ว่า

UserWarning: the 'timedelta' type is not supported, and will be written as integer values (ns frequency) to the database.

เหตุเพราะ แทนที่จะเก็บเป็น Time มันดันเปลี่ยนเป็น Integer ที่เป็นจำนวน Nanosecond แทนนั่นเอง

วิธีแก้ไข

ต้องตรวจสอบว่า มี column ใน destination table มีชนิดเป็น Time (timedelta64[ns]) ให้เอาไปบวกกับเวลาเริ่มต้น แล้ว เปลี่ยนชนิดเป็น Time แทน ดังนี้

for column in df:
    if df[column].dtype == 'timedelta64[ns]':
        df[column]=df[column].apply(lambda x: (datetime.datetime.min+x).time())

เราก็จะได้ข้อมูลที่ถูกต้องกลับมา

ตามนั้นครับ

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.