I'm using the sqlite3 module in Python 2.6.4 to store a datetime in a SQLite database. Inserting it is very easy, because sqlite automatically converts the date to a string. The problem is, when reading it it comes back as a string, but I need to reconstruct the original datetime object. How do I do this?
Asked
Active
Viewed 6.3k times
3 Answers
124
If you declare your column with a type of timestamp, you're in 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))]
See? both int (for a column declared integer) and datetime (for a column declared timestamp) survive the round-trip with the type intact.

Alex Martelli
- 854,459
- 170
- 1,222
- 1,395
-
5Thanks, Alex, it works! I'm surprised by this, because there is no mention of the TIMESTAMP type at all on http://www.sqlite.org/datatype3.html – EMP Dec 02 '09 at 23:11
-
19@Evgeny, see http://docs.python.org/library/sqlite3.html#default-adapters-and-converters -- it's not documented at sqlite.org because it's actually implemented in the Python layer, not in sqlite itself! – Alex Martelli Dec 03 '09 at 01:44
-
23I just find out it is the __detect_types=sqlite3.PARSE_DECLTYPES__ parameter of the connect function that makes fetchall returns a datetime. If you omit it you will have a unicode object. – Ponytech May 11 '12 at 15:39
-
7Seems like this fails for timezone aware values like `u'2012-01-01 18:35:24.617954-02:00'` – Paulo Scardine Jul 26 '12 at 01:58
-
I had a tangential question on this issue, but I've created a new one here: http://stackoverflow.com/questions/11840382/sqlite-python-retrieve-current-timestamp-as-datetime-object. Is the issue related? It sounds like it MIGHT be. – Dev Kanchen Aug 07 '12 at 06:29
-
@AlexMartelli the datetime value returns via SQLITE is being considered as a Tuple when I try to use strftime function. What am I doing wrong? – Volatil3 Nov 11 '12 at 16:32
-
14What is the rationale for TIMESTAMP working but not DATETIME? – Ciro Santilli OurBigBook.com Nov 24 '15 at 09:57
-
1It's not reliable ... File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/sqlite3/dbapi2.py", line 67, in convert_timestamp datepart, timepart = val.split(b" ") ValueError: not enough values to unpack (expected 2, got 1) – Wolfgang Fahl Apr 08 '20 at 08:00
-
1I'm using python 3.8 and declared my variable as DATE. After using `detect_types=sqlite3.PARSE_DECLTYPES`, sqlite3 returns a datetime.date object. Otherwise, it returns a string. – FreyGeospatial May 11 '22 at 15:48
31
It turns out that sqlite3 can do this and it's even documented, kind of - but it's pretty easy to miss or misunderstand.
What I had to do is:
- Pass the sqlite3.PARSE_COLNAMES option in the .connect() call, eg.
conn = sqlite3.connect(dbFilePath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
Put the type I wanted into the query - and for datetime, it's not actually "datetime", but "timestamp":
sql = 'SELECT jobid, startedTime as "[timestamp]" FROM job' cursor = conn.cursor() try: cursor.execute(sql) return cursor.fetchall() finally: cursor.close()
If I pass in "datetime" instead it's silently ignored and I still get a string back. Same if I omit the quotes.

EMP
- 59,148
- 53
- 164
- 220
-
9note that it's definitely `"[timestamp]"`, `[timestamp]` is silently ignored, and `.fetchone` also won't convert the types. What an odd library. – Adam Baxter Dec 11 '16 at 09:54
-
It seemed what really count is the double quote characters, neither the alias you explicitly specified nor the `as` keyword – John Wang Sep 13 '18 at 00:20
-
I have now filed https://bugs.python.org/issue35145 'sqlite3: "select *" should autoconvert datetime fields'. – Robert Pollak Nov 02 '18 at 12:43
-
1^bug issue has been migrated here: https://github.com/python/cpython/issues/79326 – FreyGeospatial May 17 '22 at 15:36
1
Note: In Python3, I had to change the SQL to something like:
SELECT jobid, startedTime as "st [timestamp]" FROM job
(I had to explicitly name the column.)

Richard Li
- 528
- 2
- 9
-
As @AdamBaxter said, what really count is the double quote characters, neither the alias you explicitly specified nor the `as` keyword. e.g., this works fine: `SELECT jobid, startedTime "[timestamp]" FROM job` – John Wang Sep 06 '18 at 21:54