Gorm AutoMigrate() and CreateTable() not working

15,913

I am pretty sure that sqlite does not have a type for your AuthIPs ([]string). I am not sure if GORM allows for you to write custom Valuer and Scanner interface methods that would allow you to convert a string to an array and back again or not, but it's something you might want to check out.

Update: Change db := d.db.AutoMigrate(&m) to db := d.db.AutoMigrate(m) to allow for the reflection to get the type name.

If you implement the tabler interface you can also better control the name of the table.

https://github.com/jinzhu/gorm/blob/master/scope.go#L305

type tabler interface {
    TableName() string
}
Share:
15,913
NlaakALD
Author by

NlaakALD

Owner Nlaak Studios (Web, Mobile, WebApp and Blochchain Development)

Updated on June 05, 2022

Comments

  • NlaakALD
    NlaakALD almost 2 years

    I have run through the related issues here and all over on google.

    I am using Gorm with SQLite3.

    Whenever I try to run either function on my struct, I get an error. When I debug and step through I see table name is "". Gorm is not getting my structs name which is models.UserAuth. If I call DropTable(models.UserAuth{}) to shows there is no table named user_auth (but at least it figured out the table name). When I browse the DB, of course there, are no tables.

    my struct is

    type UserAuth struct {
        gorm.Model
        ProfileID int      `gorm:"not null" json:"profile_id"`
        Username  string   `gorm:"size:20;unique_index" json:"username"`
        Email     string   `gorm:"type:varchar(100);unique_index" json:"email"`
        Password  string   `gorm:"not null" json:"password"`
        Remember  bool     `gorm:"not null" json:"remeber"`
        TwoFA     bool     `gorm:"not null" json:"twofa"`
        Access    int      `gorm:"not null" json:"access"`
        State     int      `gorm:"not null" json:"state"`
        LastSeen  string   `gorm:"not null" json:"lastseen"``
    }
    

    My COMMON migrate function is:

    func (d *Database) Migrate(m interface{}) {
        logEntry := fmt.Sprintf("Auto Migrating %s...", reflect.TypeOf(m))
    
        //d.db.DropTable(&models.UserAuth{})
        //d.db.CreateTable(&models.UserAuth{})
    
        // Do it the hard way
        //if d.db.HasTable(&m) == false {
        // Create table for model `User`
        //  d.db.CreateTable(&m)
        //  d.logThis.Info(fmt.Sprintf("%s %s with error %s", logEntry, "Failed", d.db.Error))
        //}
    
        // Migrate the schema
        db := d.db.AutoMigrate(&m) //<--- Line 84
        if db != nil && db.Error != nil {
            //We have an error
            d.logThis.Fatal(fmt.Sprintf("%s %s with error %s", logEntry, "Failed", db.Error))
        }
        d.logThis.Info(fmt.Sprintf("%s %s", logEntry, "Success"))
    }
    

    And finally here is how it is being called:

    app.Db.Migrate(models.UserAuth{})
    

    Actual output with debug on:

    ({PathToProject}/database/database.go:84) 
    [2018-07-23 06:12:24]  near ")": syntax error 
    
    ({PathToProject}/database/database.go:84) 
    [2018-07-23 06:12:24]  [0.99ms]  CREATE TABLE "" ( )  
    [0 rows affected or returned ] 
    

    FYI, the downvote was uncalled for - It is a legitimate issue as I have taken the gorm example on the document summary page and basically just changed the struct. And the struct is using the correct basic types (except for the slice that made it back into the code on the original post) and the error is not very helpful. I see there is a SYNTAX error before the blank table name error - but why? Did I give GORM a valid struct?

    • Flimzy
      Flimzy almost 6 years
      The error is pretty self-explanatory: You can't use a slice as a type with sqlite3. What additional question do you have?
    • NlaakALD
      NlaakALD almost 6 years
      You are correct. I had indeed removed that from the structure as well as the NewUser() function. Did not realize it made it back in. But the error remains the same - blank table name.
  • NlaakALD
    NlaakALD almost 6 years
    OMG! your right, I did not realize that made it back into the code I placed here. I had removed that. However, it is out now again - I still get the exact same error. Table Name is blank.
  • chris
    chris almost 6 years
    You shouldn't change the question asked if the answer leads to another issue. The answer should be marked and a new question opened.
  • NlaakALD
    NlaakALD almost 6 years
    Understood, but the question was not answered. As I stated, the exact same error exists, No table name. Looks like it was throwing that error before it parsed the fields and found the bad slice.
  • chris
    chris almost 6 years
    Try not passing in an interface{} reference. Call the AuthoMigrate directly. db.AutoMigrate(&UserAuth{}) or change your function to func (d *Database) MigrateUserAuth(m UserAuth) {...
  • NlaakALD
    NlaakALD almost 6 years
    Thanks for your time to answer Chris - that was the first thing I did, still blank table name. The m interface{} is coming through as models.UserAuth. update This is the answer. It does not like the interface. Using the &models.UserAuth{} directly and removing the slice ... does indeed work. Solved.
  • chris
    chris almost 6 years
    Good to hear. In db := d.db.AutoMigrate(&m) you are passing in the address of the interface, which doesn't doesn't allow for the existing reflect code to obtain the name of the type.
  • chris
    chris almost 6 years
    If this helped you out can you mark it as the answer to make it clear for others? Thanks