การแทรกวัตถุ Python datetime.datetime ลงใน MySQL


120

ฉันมีคอลัมน์วันที่ในตาราง MySQL ฉันต้องการแทรกdatetime.datetime()วัตถุลงในคอลัมน์นี้ ฉันควรใช้อะไรในคำสั่ง execute

ฉันเหนื่อย:

now = datetime.datetime(2009,5,5)

cursor.execute("INSERT INTO table
(name, id, datecolumn) VALUES (%s, %s
, %s)",("name", 4,now))

ฉันได้รับข้อผิดพลาดเป็น: "TypeError: not all arguments converted during string formatting" ฉันควรใช้อะไรแทน%s?


คุณพลาดคำพูดรอบ ๆ%s cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s , '%s')",("name", 4,now))
Sheshnath

คำตอบ:


198

สำหรับฟิลด์เวลาให้ใช้:

import time    
time.strftime('%Y-%m-%d %H:%M:%S')

ฉันคิดว่า strftime ใช้กับ datetime ด้วย


4
ยังให้แน่ใจว่าชื่อคอลัมน์ของคุณไม่ได้เป็นคำสงวน ฉันใช้เวลา 30 นาทีกว่าจะรู้ตัวว่าชื่อ "current_date" กำลังทำให้เกิดปัญหา ... ฮึ!
Pakman

2
คืออะไรtimeในตัวอย่างนี้?
James McMahon

1
J McMahon: เวลาเป็นโมดูล Python
dstromberg

จะเป็นอย่างไรหากมีคนต้องการดึงข้อมูลปีเดือนวันเพียงอย่างเดียว
Pooja Khatri

42

คุณมักจะได้รับ TypeError เนื่องจากคุณต้องการเครื่องหมายคำพูดรอบค่าคอลัมน์ข้อมูล

ลอง:

now = datetime.datetime(2009, 5, 5)

cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s, '%s')",
               ("name", 4, now))

เกี่ยวกับรูปแบบฉันประสบความสำเร็จกับคำสั่งด้านบน (ซึ่งรวมถึงมิลลิวินาที) และด้วย:

now.strftime('%Y-%m-%d %H:%M:%S')

หวังว่านี่จะช่วยได้


8
คุณอาจไม่ได้คำพูดรอบใน%s pymsql
Martin Thoma

1
คำพูดรอบ ๆ % s ที่สามทำให้เกิดข้อผิดพลาดเมื่อฉันลองสิ่งนี้
realjin

13

ลองใช้now.date()เพื่อรับDateวัตถุแทนที่จะเป็นDateTimeไฟล์.

หากไม่ได้ผลการแปลงเป็นสตริงควรใช้งานได้:

now = datetime.datetime(2009,5,5)
str_now = now.date().isoformat()
cursor.execute('INSERT INTO table (name, id, datecolumn) VALUES (%s,%s,%s)', ('name',4,str_now))

คุณไม่จำเป็นต้องใส่เครื่องหมายคำพูดรอบ ๆ พารามิเตอร์สตริงเช่น "... VALUES ('% s', '% s', '% s')"
Gareth Simpson

5

วิธีใช้งูหลามdatetime.strftime(format)ที่ '%Y-%m-%d %H:%M:%S'=

import datetime

now = datetime.datetime.utcnow()

cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s, %s)",
               ("name", 4, now.strftime('%Y-%m-%d %H:%M:%S')))

โซนเวลา

หากเขตเวลาเป็นปัญหาคุณสามารถกำหนดเขตเวลา MySQL สำหรับ UTC ได้ดังนี้:

cursor.execute("SET time_zone = '+00:00'")

และสามารถกำหนดเขตเวลาได้ใน Python:

now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)

เอกสาร MySQL

MySQL รับรู้ค่า DATETIME และ TIMESTAMP ในรูปแบบเหล่านี้:

เป็นสตริงทั้งใน'YYYY-MM-DD HH: MM: SS'หรือ'YY-MM-DD HH: MM: SS' รูปแบบ อนุญาตให้ใช้ไวยากรณ์แบบ "ผ่อนคลาย" ได้เช่นกัน: อักขระเครื่องหมายวรรคตอนใด ๆ อาจใช้เป็นตัวคั่นระหว่างส่วนวันที่หรือส่วนของเวลา ตัวอย่างเช่น '2012-12-31 11:30:45', '2012 ^ 12 ^ 31 11 + 30 + 45', '2012/12/31 11 * 30 * 45' และ '2012 @ 12 @ 31 11 ^ 30 ^ 45 'เทียบเท่า

ตัวคั่นเพียงตัวเดียวที่รับรู้ระหว่างส่วนวันที่และเวลาและเศษส่วนของวินาทีคือจุดทศนิยม

ส่วนของวันที่และเวลาสามารถคั่นด้วย T แทนที่จะเว้นวรรค ตัวอย่างเช่น '2012-12-31 11:30:45' '2012-12-31T11: 30: 45' เทียบเท่า

เป็นสตริงที่ไม่มีตัวคั่นในรูปแบบ "YYYYMMDDHHMMSS" หรือ "YYMMDDHHMMSS" โดยมีเงื่อนไขว่าสตริงมีความหมายว่าเป็นวันที่ ตัวอย่างเช่น '20070523091528' และ '070523091528' ถูกตีความว่า '2007-05-23 09:15:28' แต่ '071122129015' ผิดกฎหมาย (มีส่วนนาทีที่ไร้สาระ) และกลายเป็น '0000-00-00 00: 00:00'

เป็นตัวเลขในรูปแบบ YYYYMMDDHHMMSS หรือ YYMMDDHHMMSS โดยมีเงื่อนไขว่าตัวเลขนั้นเหมาะสมกับวันที่ ตัวอย่างเช่น 19830905132800 และ 830905132800 จะตีความเป็น "1983-09-05 13:28:00"


3

คุณกำลังเชื่อมต่อกับฐานข้อมูลใด ฉันรู้ว่า Oracle มีความพิถีพิถันเกี่ยวกับรูปแบบวันที่และชอบรูปแบบISO 8601

** หมายเหตุ: อ๊ะฉันเพิ่งอ่านคุณอยู่ใน MySQL เพียงจัดรูปแบบวันที่และลองเป็นการเรียก SQL โดยตรงแยกต่างหากเพื่อทดสอบ

ใน Python คุณจะได้รับวันที่ ISO เช่น

now.isoformat()

ตัวอย่างเช่น Oracle ชอบวันที่เช่น

insert into x values(99, '31-may-09');

ขึ้นอยู่กับฐานข้อมูลของคุณหากเป็น Oracle คุณอาจต้อง TO_DATE:

insert into x
values(99, to_date('2009/05/31:12:00:00AM', 'yyyy/mm/dd:hh:mi:ssam'));

การใช้งานทั่วไปของ TO_DATE คือ:

TO_DATE(<string>, '<format>')

หากใช้ฐานข้อมูลอื่น (ฉันเห็นเคอร์เซอร์และคิดว่า Oracle ฉันอาจผิด) ให้ตรวจสอบเครื่องมือรูปแบบวันที่ สำหรับ MySQL คือ DATE_FORMAT () และ SQL Server เป็น CONVERT

นอกจากนี้การใช้เครื่องมืออย่างSQLAlchemyจะลบความแตกต่างเช่นนี้และทำให้ชีวิตของคุณง่ายขึ้น


ฉันไม่แนะนำให้ใช้ datetime.isoformat () เพราะถ้าคุณใช้วัตถุที่ทราบเขตเวลาสตริงที่สร้างขึ้นจะรวมข้อมูลเขตเวลาและไม่ตรงกับรูปแบบ mysql ที่ต้องการอีกต่อไป
frankster

0

หากคุณแค่ใช้ python datetime.date (ไม่ใช่ datetime.datetime แบบเต็ม) ให้แคสวันที่เป็นสตริง มันง่ายมากและใช้ได้กับฉัน (mysql, python 2.7, Ubuntu) คอลัมน์published_dateเป็นฟิลด์วัน MySQL, ตัวแปรหลามเป็น publish_datedatetime.date

# make the record for the passed link info
sql_stmt = "INSERT INTO snippet_links (" + \
    "link_headline, link_url, published_date, author, source, coco_id, link_id)" + \
    "VALUES(%s, %s, %s, %s, %s, %s, %s) ;"

sql_data = ( title, link, str(publish_date), \
             author, posted_by, \
             str(coco_id), str(link_id) )

try:
    dbc.execute(sql_stmt, sql_data )
except Exception, e:
    ...

0

เมื่อเทียบกับ t-sql

สิ่งนี้ล้มเหลว:

select CONVERT(datetime,'2019-09-13 09:04:35.823312',21)

งานนี้:

select CONVERT(datetime,'2019-09-13 09:04:35.823',21)

ทางที่ง่าย:

regexp = re.compile(r'\.(\d{6})')
def to_splunk_iso(dt):
    """Converts the datetime object to Splunk isoformat string."""
    # 6-digits string.
    microseconds = regexp.search(dt).group(1)
    return regexp.sub('.%d' % round(float(microseconds) / 1000), dt)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.