-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
'sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time' with datetime('now') #190
Comments
|
So you need to use |
I still have the problem if I cast to text. 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 cast(datetime('now') as text)").Scan(&d)
if err != nil {
t.Fatal("Failed to scan datetime:", err)
}
}
It seems the type was already text.
|
I've had to work around this using the following code
|
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 got a similar problem. I've got a table with two columns,
A normal |
I don't understand what is |
setting the DNS param solved this problem for me. :) user:pass@tcp(endpoint:3306)/dbname?parseTime=true |
it's an option just provided for mysql driver. |
"?parseTime=true" does it for me. I guess this would be very common.. no? Kinda a catcha that easily costs people hours. |
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. for rows.Next() {
var v time.Time
rows.Scan(&v) // driver cant know v is time.Time
} |
?parseTime=true is only supported by the MySQL driver (as of the time I'm writing this at least). 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 |
Or you can scan the time.Time with making simple type converter. See https://golang.org/pkg/database/sql/#Scanner package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/mattn/go-sqlite3"
)
type MyTime time.Time
func (t *MyTime) Scan(v interface{}) error {
// Should be more strictly to check this type.
vt, err := time.Parse("2006-01-02 15:04:05", string(v.([]byte)))
if err != nil {
return err
}
*t = MyTime(vt)
return nil
}
func main() {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err := db.Query(`select datetime('now')`)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var dt time.Time
err = rows.Scan((*MyTime)(&dt))
if err != nil {
log.Fatal(err)
}
fmt.Println(dt)
}
} |
Answered; Closed |
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.
The text was updated successfully, but these errors were encountered: