go-sqlite3: 'sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time' with datetime('now')
sqlite3_column_decltype() returns NULL when it’s an expression.
I’m not sure it’s a bug.
I was thinking that maybe go-sqlite3 could guess that the string is a datetime but that could cause problem when someone want a text timestamp on purpose.
It could be easier to do the work on the user side since we know if we expect a string or a datetime/date/timestamp.
func TestDateTimeNow(t *testing.T) {
tempFilename := TempFilename()
db, err := sql.Open("sqlite3", tempFilename)
if err != nil {
t.Fatal("Failed to open database:", err)
}
defer db.Close()
var d time.Time
err = db.QueryRow("select datetime('now')").Scan(&d)
if err != nil {
t.Fatal("Failed to scan datetime:", err)
}
}
--- FAIL: TestDateTimeNow (0.02s)
sqlite3_test.go:917: Failed to scan datetime: sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time
FAIL
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 1
- Comments: 16 (6 by maintainers)
Or you can scan the time.Time with making simple type converter. See https://golang.org/pkg/database/sql/#Scanner
setting the DNS param solved this problem for me. 😃
user:pass@tcp(endpoint:3306)/dbname?parseTime=true
No, go’s database/sql has three layers.
Most of type conversion is done in database/sql. So driver can’t know what type of pointers are passed into the driver.
I just noticed that if you create the table with the column type datetime (which appears to map to text) scanning works, if its created as an integer it doesn’t.
Not sure if this is your problem too?
I’ve had to work around this using the following code
?parseTime=true is only supported by the MySQL driver (as of the time I’m writing this at least). i have not read the source so take this with a grain of salt, but from experimenting and reading docs/issues it seems like this driver looks at the schema of the table in deciding how to scan.
If you use a (explicit) text data type for the column, time.Time values will serialize fine into the database, but will throw an error if you try to select (scan) back into Go.
If you use a ‘datetime’ or ‘timestamp’ column type for your time.Time column, it will go in fine both ways, and the underlying data type will remain the same, as a ‘text.’
If you
SELECT typeof(mytimecol) FROM mytable
you will see ‘text’ for every row.min(login)
has no declared type. So this code is not executed. Currently, any expression (except simple reference to a column) returning a date (i.e.datetime('now')
,min(login)
, …) cannot be scanned as a time.Time. The driver needs to know the destination/go type (i.e., time.Time)…I’ve got a similar problem. I’ve got a table with two columns,
id integer
andlogin timestamp
. I’m trying to useselect id, min(login)
and scan it into anint64
and atime.Time
. I get this error:A normal
select id, login
works fine, however. Is there a different SQL syntax I should be using, is this expected behavior, or is this a bug? I can useorder by login limit 1
withQueryRow()
to just get the first row, but that seems kind of ineffiecient.