Skip to content
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

How can I set up atlas to only migrate some models? #24

Open
deerbone opened this issue Nov 30, 2023 · 3 comments
Open

How can I set up atlas to only migrate some models? #24

deerbone opened this issue Nov 30, 2023 · 3 comments
Assignees

Comments

@deerbone
Copy link

deerbone commented Nov 30, 2023

Hi,
is there a way to set-up atlas to specify what models I want to exclude?

In our project we define some helper models that we do not migrate to the DB, we only work with them in the program itself.

Small example that doesn't really make sense:

// Model is a basic abstract db model struct. Custom Model to not utilize Gorm soft delete.
type Model struct {
	ID        uuid.UUID `gorm:"type:uuid;primaryKey"`
	CreatedAt time.Time `gorm:"not null"`
	UpdatedAt time.Time `gorm:"not null"`
}

type User struct {
	Model
	Name    string
	Surname string
}

type UserWithAddress struct {
	User    User   `gorm:"embedded"`
	Address string `gorm:"column:address"`
}
// main.go
package main

import ...

func main() {
	db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	// Migrate the schema
	if err := db.AutoMigrate(&model.User{}); err != nil {
		panic(err)
	}

	// Create a user with an embedded address
	user := model.UserWithAddress{
		User: model.User{
			Name:    "John",
			Surname: "Doe",
		},
		Address: "123 Main St.",
	}
	db.Create(&user)

	// Retrieve the user from the database
	var retrievedUser model.User
	db.First(&retrievedUser)

	// Print the retrieved user
	fmt.Printf("Retrieved User: %+v\n", retrievedUser)
}

atlas.hcl

data "external_schema" "gorm" {
  program = [
    "go",
    "run",
    "-mod=mod",
    "ariga.io/atlas-provider-gorm",
    "load",
    "--path", "./model",
    "--dialect", "sqlite", // mysql | postgres | sqlite
  ]
}

env "gorm" {
  src = data.external_schema.gorm.url
  dev = "sqlite://file?mode=memory"
  migration {
    dir = "file://migrations"
  }
  format {
    migrate {
      diff = "{{ sql . \"  \" }}"
    }
  }
  lint  {
    latest=10 // check against the latest 10 migrations
  }
}

What gets generated with atlas migrate diff

-- Create "user_with_addresses" table
CREATE TABLE `user_with_addresses` (
  `id` uuid NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `name` text NULL,
  `surname` text NULL,
  `address` text NULL,
  PRIMARY KEY (`id`)
);
-- Create "models" table
CREATE TABLE `models` (
  `id` uuid NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
);

The schema that GORM creates:

CREATE TABLE `users` (
    `id` uuid,
    `created_at` datetime NOT NULL,
    `updated_at` datetime NOT NULL,
    `name` text,
    `surname` text,
    PRIMARY KEY (`id`)
);

Is there a way for me to achieve this?

@deerbone deerbone changed the title GORM embedded notation support GORM embedded notation issue Nov 30, 2023
@deerbone deerbone changed the title GORM embedded notation issue How can I ignore certain models from being managed? Dec 1, 2023
@deerbone deerbone changed the title How can I ignore certain models from being managed? How can I set up gorm to only migrate some models? Dec 1, 2023
@deerbone deerbone changed the title How can I set up gorm to only migrate some models? How can I set up atlas to only migrate some models? Dec 1, 2023
@indeedhat
Copy link

Um guessing at this point you have found a solution or given up but in case someone else ends up here:

It seems that atlas doesn't support the embedded struct tag at the moment, you can achieve what you want by embedding the struct itself, not ideal but its a stop gap until the embedded tag gets implemented

type UserWithAddress struct {
	User

	Address string `gorm:"column:address"`
}

@giautm giautm self-assigned this May 5, 2024
@rotemtam
Copy link
Member

rotemtam commented May 5, 2024

Hey,

If you need something more involved, I suggest using Go Program Mode which give you ultimate control on the models the provider uses as the desired schema.

@fzyukio
Copy link

fzyukio commented Sep 26, 2024

Same issue, my workaround is to declare abstract models in a different package, and concrete models in the package that I provide to atlas, e.g.:

# ./db/abstract/models.go:
type BaseModel struct {
	ID   int64      `gorm:"primarykey;autoIncrement"`
}

# ./db/concrete/models.go:

import base "./db/abstract"

type User struct {
	base.BaseModel
	Username  string 
	...
}

and the hcl file:

data "external_schema" "gorm" {
  program = [
    "go",
    "run",
    "ariga.io/atlas-provider-gorm",
    "load",
    "--path", "./db/concrete",
    "--dialect", "mysql",
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants