web-dev-qa-db-fra.com

Insertion d'un objet datetime.datetime Python dans MySQL

J'ai une colonne de date dans une table MySQL. Je veux insérer un objet datetime.datetime() dans cette colonne. Que devrais-je utiliser dans l'instruction execute?

J'ai essayé:

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

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

Je reçois une erreur en tant que: "TypeError: not all arguments converted during string formatting" Que dois-je utiliser à la place de %s?

100
Scaraffe

Pour un champ temporel, utilisez:

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

Je pense que strftime s'applique également à datetime.

169
g33kz0r

Vous obtenez probablement l'erreur TypeError car vous avez besoin de guillemets autour de la valeur datecolumn.

Essayer:

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

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

En ce qui concerne le format, j'ai eu du succès avec la commande ci-dessus (qui inclut les millisecondes) et avec:

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

J'espère que cela t'aides.

38
Edvinas

Essayez d'utiliser now.date() pour obtenir un objet Date plutôt que DateTime.

Si cela ne fonctionne pas, alors le convertir en chaîne devrait fonctionner:

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

À quelle base de données vous connectez-vous? Je sais que Oracle peut être difficile en ce qui concerne les formats de date et aime ISO 8601 format.

** Note: Oups, je viens de lire que vous êtes sur MySQL. Il suffit de formater la date et de l’essayer en tant qu’appel direct SQL distinct à tester.

En Python, vous pouvez obtenir une date ISO comme

now.isoformat()

Par exemple, Oracle aime les dates comme

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

Selon votre base de données, s'il s'agit d'Oracle, vous devrez peut-être TO_DATE le:

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

L'usage général de TO_DATE est le suivant:

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

Si vous utilisez une autre base de données (j'ai vu le curseur et pensé à Oracle; je peux me tromper), vérifiez leurs outils de format de date. Pour MySQL, il s'agit de DATE_FORMAT () et SQL Server, de type CONVERT.

Également utiliser un outil tel que SQLAlchemy supprimera des différences de ce type et vous facilitera la vie.

2
Ryan Christensen

Si vous utilisez simplement un datetime.date python (et non un datetime.datetime complet), il suffit de transtyper la date en tant que chaîne. C’est très simple et fonctionne pour moi (mysql, python 2.7, Ubuntu). La colonne published_date est un champ date MySQL, la variable python publish_date est 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
jbartas

Utilisez la méthode Python datetime.strftime(format) , où 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')))

Fuseaux horaires

Si les fuseaux horaires sont un problème, le fuseau horaire MySQL peut être défini pour UTC comme suit:

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

Et le fuseau horaire peut être défini en Python:

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

Documentation MySQL

MySQL reconnaît les valeurs DATETIME et TIMESTAMP dans les formats suivants:

En tant que chaîne au format 'AAAA-MM-JJ HH: MM: SS' ou 'AA-MM-JJ HH: MM: SS' . Une syntaxe "assouplie" est également autorisée ici: tout caractère de ponctuation peut être utilisé comme séparateur entre les parties de date ou les parties d’heure. Par exemple, '2012-12-31 11:30:45', '2012 ^ 12 ^ 31 11 + 30 + 45', '2012/12/31 11 * 30 * 45' et '2012 @ 12 @ 31 11 ^ 30 ^ 45 'sont équivalents.

Le seul séparateur reconnu entre une partie de date et heure et une partie de fraction de seconde est le point décimal.

Les parties de date et d’heure peuvent être séparées par T plutôt que par un espace. Par exemple, '2012-12-31 11:30:45' '2012-12-31T11: 30: 45' sont équivalents.

En tant que chaîne sans délimiteurs au format "AAAAMMJJHHMMSS" ou "YYMMDDHHMMSS", à condition que la chaîne ait un sens en tant que date. Par exemple, "20070523091528" et "070523091528" sont interprétés comme "2007-05-23 09:15:28", mais "071122129015" est illégal (il comporte une partie minute absurde) et devient "0000-00-00 00: 00:00 '.

Un nombre au format AAAAMMJJHHMMSS ou YYMMDDHHMMSS, à condition que le numéro ait un sens en tant que date. Par exemple, 19830905132800 et 830905132800 sont interprétés comme "1983-09-05 13:28:00".

0