Einfügen eines Python-Objekts datetime.datetime in MySQL

120

Ich habe eine Datumsspalte in einer MySQL-Tabelle. Ich möchte ein datetime.datetime()Objekt in diese Spalte einfügen . Was soll ich in der execute-Anweisung verwenden?

Ich habe versucht:

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

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

Ich erhalte die Fehlermeldung: "TypeError: not all arguments converted during string formatting" Was soll ich anstelle von verwenden %s?

Peter Mortensen
quelle
Sie haben Zitate verpasst%s cursor.execute("INSERT INTO table (name, id, datecolumn) VALUES (%s, %s , '%s')",("name", 4,now))
Sheshnath

Antworten:

198

Verwenden Sie für ein Zeitfeld:

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

Ich denke, strftime gilt auch für datetime.

g33kz0r
quelle
4
Stellen Sie außerdem sicher, dass Ihr Spaltenname kein reserviertes Wort ist . Ich habe 30 Minuten gebraucht, um festzustellen, dass der Name "current_date" Probleme verursacht hat ... ugh!
Pakman
2
Was ist timein diesem Beispiel?
James McMahon
1
J McMahon: Zeit ist ein Python-Modul.
Dstromberg
Was ist, wenn jemand das einzige Jahr, den einzigen Monat und den einzigen Tag abrufen möchte?
Pooja Khatri
42

Sie erhalten höchstwahrscheinlich den TypeError, da Sie Anführungszeichen um den Wert der Datumsspalte benötigen.

Versuchen:

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

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

In Bezug auf das Format hatte ich Erfolg mit dem obigen Befehl (der die Millisekunden enthält) und mit:

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

Hoffe das hilft.

Edvinas
quelle
8
Möglicherweise haben Sie keine Anführungszeichen %sin pymsql.
Martin Thoma
1
Anführungszeichen um das dritte% s verursachen Fehler, wenn ich dies versuche.
Realjin
13

Versuchen Sie now.date(), ein DateObjekt anstelle eines zu erhalten DateTime.

Wenn das nicht funktioniert, sollte das Konvertieren in einen String funktionieren:

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))
Wogan
quelle
Sie müssen keine Anführungszeichen um die Zeichenfolgenparameter hinzufügen, z. B. "... VALUES ('% s', '% s', '% s')"
Gareth Simpson,
5

Verwenden Sie die Python-Methode datetime.strftime(format), wobei 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')))

Zeitzonen

Wenn Zeitzonen ein Problem darstellen, kann die MySQL-Zeitzone für UTC wie folgt eingestellt werden:

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

Und die Zeitzone kann in Python eingestellt werden:

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

MySQL-Dokumentation

MySQL erkennt DATETIME- und TIMESTAMP-Werte in folgenden Formaten:

Als Zeichenfolge im Format "JJJJ-MM-TT HH: MM: SS" oder "JJ-MM-TT HH: MM: SS" . Auch hier ist eine „entspannte“ Syntax zulässig: Jedes Interpunktionszeichen kann als Trennzeichen zwischen Datums- oder Zeitteilen verwendet werden. Zum Beispiel '2012-12-31 11:30:45', '2012 ^ 12 ^ 31 11 + 30 + 45', '2012/12/31 11 * 30 * 45' und '2012 @ 12 @ 31 11 ^ 30 ^ 45 'sind gleichwertig.

Das einzige Trennzeichen zwischen einem Datums- und Zeitteil und einem Sekundenbruchteil ist der Dezimalpunkt.

Die Datums- und Uhrzeitteile können durch T und nicht durch ein Leerzeichen getrennt werden. Beispiel: '2012-12-31 11:30:45' '2012-12-31T11: 30: 45' sind äquivalent.

Als Zeichenfolge ohne Trennzeichen im Format 'JJJJMMTTHHMMSS' oder 'JJJMMTTHHMMSS', sofern die Zeichenfolge als Datum sinnvoll ist. Beispielsweise werden '20070523091528' und '070523091528' als '2007-05-23 09:15:28' interpretiert, aber '071122129015' ist illegal (es hat einen unsinnigen winzigen Teil) und wird zu '0000-00-00 00: 00:00 '.

Als Nummer im Format JJJJMMTTHHMMSS oder JJJMMTTHHMMSS, sofern die Nummer als Datum sinnvoll ist. Beispielsweise werden 19830905132800 und 830905132800 als "1983-09-05 13:28:00" interpretiert.

Christopher Peisert
quelle
3

Mit welcher Datenbank verbinden Sie sich? Ich weiß, dass Oracle bei Datumsformaten wählerisch sein kann und das ISO 8601- Format mag .

** Hinweis: Ups, ich habe gerade gelesen, dass Sie auf MySQL sind. Formatieren Sie einfach das Datum und versuchen Sie es als separaten direkten SQL-Aufruf zum Testen.

In Python können Sie ein ISO-Datum wie erhalten

now.isoformat()

Zum Beispiel mag Oracle Daten wie

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

Abhängig von Ihrer Datenbank müssen Sie Oracle möglicherweise TO_DATE:

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

Die allgemeine Verwendung von TO_DATE ist:

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

Wenn Sie eine andere Datenbank verwenden (ich habe den Cursor gesehen und dachte, Oracle; ich könnte mich irren), überprüfen Sie deren Datumsformat-Tools. Für MySQL ist es DATE_FORMAT () und für SQL Server ist es CONVERT.

Auch die Verwendung eines Tools wie SQLAlchemy beseitigt solche Unterschiede und erleichtert Ihnen das Leben.

Ryan Christensen
quelle
Ich empfehle nicht, datetime.isoformat () zu verwenden, da bei Verwendung eines zeitzonensensitiven Objekts die generierte Zeichenfolge Zeitzonendaten enthält und nicht mehr mit dem erforderlichen MySQL-Format übereinstimmt.
Frankster
0

Wenn Sie nur eine Python-Datei datetime.date verwenden (keine vollständige datetime.datetime), setzen Sie das Datum einfach als Zeichenfolge um. Dies ist sehr einfach und funktioniert für mich (MySQL, Python 2.7, Ubuntu). Die Spalte published_dateist ein MySQL-Datumsfeld, die Python-Variable publish_dateist 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:
    ...
jbartas
quelle
0

beim iserting in t-sql

das schlägt fehl:

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

das funktioniert:

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

einfacher Weg:

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)
Krzysztof Drewicz
quelle