Comment lire datetime à partir de sqlite en tant que datetime au lieu de string en Python?

J'utilise le module sqlite3 en python 2.6.4 pour stocker un datetime dans une base de données SQLite. L'insérer est très facile, car sqlite convertit automatiquement la date en une chaîne. Le problème est, en le lisant, il revient comme une chaîne, mais j'ai besoin de reconstruire l'objet datetime d'origine. Comment dois-je faire?

57

3 réponses

Si vous déclarez votre colonne avec un type d'horodatage, vous êtes dans clover:

>>> db = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES)
>>> c = db.cursor()
>>> c.execute('create table foo (bar integer, baz timestamp)')
<sqlite3.Cursor object at 0x40fc50>
>>> c.execute('insert into foo values(?, ?)', (23, datetime.datetime.now()))
<sqlite3.Cursor object at 0x40fc50>
>>> c.execute('select * from foo')
<sqlite3.Cursor object at 0x40fc50>
>>> c.fetchall()
[(23, datetime.datetime(2009, 12, 1, 19, 31, 1, 40113))]

Tu vois? int (pour une colonne déclarée entière) et datetime (pour une colonne déclarée horodatage) survivent à l'aller-retour avec le type intact.

97
répondu Alex Martelli 2009-12-02 03:33:05

Il s'avère que sqlite3 peut le faire et c'est même documenté, en quelque sorte - mais c'est assez facile à manquer ou à mal comprendre.

Ce que je devais faire est:

  • passez le sqlite3.PARSE_COLNAMES option dans le .connect() appel, par exemple.
conn = sqlite3.connect(dbFilePath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
  • Mettez le type que je voulais dans la requête - et pour datetime, ce n'est pas réellement "datetime", mais "timestamp":

    sql = 'SELECT jobid, startedTime as "[timestamp]" FROM job'
    
    cursor = conn.cursor()
    try:
        cursor.execute(sql)
        return cursor.fetchall()
    finally:
        cursor.close()
    

Si je passe dans "datetime" à la place c'est silencieusement ignoré et je reçois toujours une chaîne de retour. Même si je omettre les guillemets.

18
répondu EMP 2009-12-02 21:48:30

Note: En Python3, j'ai dû changer le SQL en quelque chose comme:

SELECT jobid, startedTime as "st [timestamp]" FROM job

(je devais nommer explicitement la colonne.)

1
répondu Richard Li 2018-01-24 18:58:22