Вставлення об’єкта 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')

Я думаю, що стрипінг також стосується дати.


4
Також переконайтесь, що назва стовпця не є зарезервованим словом . У мене було 30 хвилин, щоб зрозуміти, що назва "current_date" спричиняло проблеми ... Тьфу!
Пакман

2
Що timeв цьому прикладі?
Джеймс Макмахон

1
J McMahon: час - модуль Python.
дстромберг

Що робити, якщо хтось хоче отримати єдиний рік, місяць, день?
Пуджа Хатрі

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.
Мартін Тома

1
Цитати навколо третього% s викликають помилку, коли я намагаюся це зробити.
realjin

13

Спробуйте скористатися, now.date()щоб отримати Dateоб’єкт, а не a 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')"
Гарет Сімпсон,

5

Використовуйте метод Python datetime.strftime(format), де 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.
франкстер

0

Якщо ви просто використовуєте python datetime.date (не повний datetime.datetime), просто переведіть дату як рядок. Це дуже просто і працює для мене (mysql, python 2.7, Ubuntu). Стовпець published_date- це поле дати MySQL, змінна python publish_dateє datetime.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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.