Chèn một đối tượng datetime.datetime trong Python vào MySQL


120

Tôi có cột ngày trong bảng MySQL. Tôi muốn chèn một datetime.datetime()đối tượng vào cột này. Tôi nên sử dụng điều gì trong câu lệnh thực thi?

Tôi đã thử:

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

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

Tôi gặp lỗi như: "TypeError: not all arguments converted during string formatting" Tôi nên sử dụng cái gì thay thế %s?


bạn bị mất dấu ngoặc kép quanh%s cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s , '%s')",("name", 4,now))
Sheshnath

Câu trả lời:


198

Đối với trường thời gian, hãy sử dụng:

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

Tôi nghĩ rằng strftime cũng áp dụng cho datetime.


4
Ngoài ra, hãy đảm bảo rằng tên cột của bạn không phải là một từ dành riêng . Tôi mất 30 phút để nhận ra tên "current_date" đang gây ra vấn đề ... ugh!
Pakman

2
Là gì timetrong ví dụ này?
James McMahon

1
J McMahon: thời gian là một mô-đun Python.
dstromberg

Điều gì sẽ xảy ra nếu ai đó muốn lấy Năm, Tháng, Ngày duy nhất?
Pooja Khatri

42

Rất có thể bạn nhận được TypeError vì bạn cần dấu ngoặc kép xung quanh giá trị cột dữ liệu.

Thử:

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

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

Liên quan đến định dạng, tôi đã thành công với lệnh trên (bao gồm phần nghìn giây) và với:

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

Hi vọng điêu nay co ich.


8
Bạn có thể không có dấu ngoặc kép quanh %strong pymsql.
Martin Thoma

1
Trích dẫn xung quanh% s thứ ba gây ra lỗi khi tôi thử điều này.
realjin

13

Hãy thử sử dụng now.date()để lấy một Dateđối tượng hơn là một DateTime.

Nếu điều đó không hoạt động, thì việc chuyển đổi thành chuỗi sẽ hoạt động:

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))

Bạn không cần phải thêm dấu ngoặc kép quanh các tham số chuỗi tức là "... VALUES ( '% s', '% s', '% s')"
Gareth Simpson

5

Sử dụng phương thức Python datetime.strftime(format), trong đó 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')))

Múi giờ

Nếu các múi giờ là mối quan tâm, múi giờ MySQL có thể được đặt cho UTC như sau:

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

Và múi giờ có thể được đặt bằng Python:

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

Tài liệu MySQL

MySQL nhận dạng các giá trị DATETIME và TIMESTAMP ở các định dạng sau:

Dưới dạng chuỗi có định dạng 'YYYY-MM-DD HH: MM: SS' hoặc 'YY-MM-DD HH: MM: SS' . Ở đây cũng cho phép cú pháp "thoải mái": Bất kỳ ký tự dấu câu nào cũng có thể được sử dụng làm dấu phân cách giữa các phần ngày hoặc các phần thời gian. Ví dụ: '2012-12-31 11:30:45', '2012 ^ 12 ^ 31 11 + 30 + 45', '2012/12/31 11 * 30 * 45' và '2012 @ 12 @ 31 11 ^ 30 ^ 45 'là tương đương.

Dấu phân cách duy nhất được nhận dạng giữa phần ngày và giờ và phần giây phân số là dấu thập phân.

Các phần ngày và giờ có thể được phân tách bằng T chứ không phải là dấu cách. Ví dụ: '2012-12-31 11:30:45' '2012-12-31T11: 30: 45' tương đương.

Là một chuỗi không có dấu phân cách ở định dạng 'YYYYMMDDHHMMSS' hoặc 'YYMMDDHHMMSS', với điều kiện là chuỗi có ý nghĩa như một ngày tháng. Ví dụ: '20070523091528' và '070523091528' được hiểu là '2007-05-23 09:15:28', nhưng '071122129015' là bất hợp pháp (nó có phần phút vô nghĩa) và trở thành '0000-00-00 00: 00:00 '.

Dưới dạng một số ở định dạng YYYYMMDDHHMMSS hoặc YYMMDDHHMMSS, miễn là số có ý nghĩa như một ngày tháng. Ví dụ: 19830905132800 và 830905132800 được hiểu là '1983-09-05 13:28:00'.


3

Bạn đang kết nối với cơ sở dữ liệu nào? Tôi biết Oracle có thể kén chọn định dạng ngày tháng và thích định dạng ISO 8601 .

** Lưu ý: Rất tiếc, tôi vừa đọc được rằng bạn đang sử dụng MySQL. Chỉ cần định dạng ngày và thử nó như một cuộc gọi SQL trực tiếp riêng biệt để kiểm tra.

Trong Python, bạn có thể nhận được ngày ISO như

now.isoformat()

Ví dụ, Oracle thích những ngày như

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

Tùy thuộc vào cơ sở dữ liệu của bạn, nếu đó là Oracle, bạn có thể cần TO_DATE nó:

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

Việc sử dụng chung của TO_DATE là:

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

Nếu sử dụng cơ sở dữ liệu khác (tôi nhìn thấy con trỏ và nghĩ là Oracle; có thể tôi đã nhầm) thì hãy kiểm tra các công cụ định dạng ngày của họ. Đối với MySQL, nó là DATE_FORMAT () và SQL Server thì nó là CONVERT.

Ngoài ra, sử dụng một công cụ như SQLAlchemy sẽ loại bỏ những khác biệt như thế này và giúp cuộc sống của bạn trở nên dễ dàng.


Tôi không khuyên bạn nên sử dụng datetime.isoformat () vì nếu bạn sử dụng đối tượng nhận biết múi giờ, chuỗi được tạo bao gồm dữ liệu múi giờ và không còn khớp với định dạng mysql bắt buộc.
Frankster

0

Nếu bạn chỉ đang sử dụng một tệp datetime.date trong python (không phải datetime.datetime đầy đủ), chỉ cần truyền ngày dưới dạng chuỗi. Điều này rất đơn giản và phù hợp với tôi (mysql, python 2.7, Ubuntu). Cột published_datelà một trường ngày MySQL, biến python 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

khi chuyển thành t-sql

điều này không thành công:

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

những công việc này:

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

cách dễ dàng:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.