jmoiron / modl

golang database modelling library
MIT License
479 stars 48 forks source link

Panic when insert to postgres with autoincrement #31

Closed rmrio closed 9 years ago

rmrio commented 9 years ago

The following simple insert code fails with modl, but ok with gorp.

type Person struct {
    Id   int
    Name string
}

func main() {

    db, err := sql.Open("postgres", "user=modl_user password=qwerty dbname=modl_test sslmode=disable")
    if err != nil {
        fmt.Println(err)
    }

    dbmap := &modl.DbMap{Db: db, Dialect: modl.PostgresDialect{}}
    dbmap.TraceOn("", log.New(os.Stdout, "modltest: ", log.Lmicroseconds))
    dbmap.AddTableWithName(Person{}, "persons").SetKeys(true, "Id")

    err = dbmap.CreateTablesIfNotExists()
    if err != nil {
        fmt.Println(err)
    }

    person := &Person{}
    person.Name = "Alex Smith"
    err = dbmap.Insert(person)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("Person id", person.Id)
}

Tested on go1.4 + postgres 9.4 The output:

modltest: 17:18:46.762624 create table if not exists "persons" ("id" serial not null primary key , "name" varchar(255)); [[]]
modltest: 17:18:46.767508 insert into "persons" ("id","name") values (default,$1) returning id; [Alex Smith]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x15744b]

goroutine 16 [running]:
runtime.panic(0x25c8a0, 0x3f01c4)
    /usr/local/go/src/pkg/runtime/panic.c:279 +0xf5
github.com/jmoiron/sqlx.(*DB).Queryx(0x0, 0xc2080182d0, 0x45, 0xc2080009c0, 0x1, 0x1, 0x3f31a8, 0x0, 0x0)
    /Users/me/Code/go/src/github.com/jmoiron/sqlx/sqlx.go:326 +0x3b
github.com/rmrio/modl.(*tracingHandle).Queryx(0xc208044b60, 0xc2080182d0, 0x45, 0xc2080009c0, 0x1, 0x1, 0x1, 0x0, 0x0)
    /Users/me/Code/go/src/github.com/rmrio/modl/handle.go:40 +0xe2
github.com/rmrio/modl.PostgresDialect.InsertAutoIncr(0x0, 0x0, 0x496870, 0xc2080041e0, 0xc2080182d0, 0x45, 0xc2080009c0, 0x1, 0x1, 0x0, ...)
    /Users/me/Code/go/src/github.com/rmrio/modl/dialect.go:264 +0xcc
github.com/rmrio/modl.(*PostgresDialect).InsertAutoIncr(0xc2080005a0, 0x496870, 0xc2080041e0, 0xc2080182d0, 0x45, 0xc2080009c0, 0x1, 0x1, 0x1, 0x0, ...)
    <autogenerated>:46 +0x106
github.com/rmrio/modl.insert(0xc2080041e0, 0x496870, 0xc2080041e0, 0xc208079ed0, 0x1, 0x1, 0x0, 0x0)
    /Users/me/Code/go/src/github.com/rmrio/modl/modl.go:334 +0x375
github.com/rmrio/modl.(*DbMap).Insert(0xc2080041e0, 0xc208079ed0, 0x1, 0x1, 0x0, 0x0)
    /Users/me/Code/go/src/github.com/rmrio/modl/dbmap.go:273 +0x90

I'm not sure I can solve this problem, but I'll try

jmoiron commented 9 years ago

modl relies on sqlx for a lot of underlying database work (including serialization), and its sqlx.DB is nil in your example. It's for this reason the modl.NewDbMap function is provided. Try instead:

dbmap := modl.NewDbMap(db, modl.PostgresDialect{})

This will initialize the name mapper as well as the dbx handle.

rmrio commented 9 years ago

Thank you for the explanation and for the library