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

Adding column and running an update query on the table to populate data in that column does not run in a single migration #1146

Open
sumit-anantwar opened this issue Aug 28, 2024 · 1 comment

Comments

@sumit-anantwar
Copy link

sumit-anantwar commented Aug 28, 2024

Describe the Bug
We need to add two columns to a table and then populate the new columns with some data.
Doing this in a single migration fails with error Invalid column name

Steps to Reproduce
Steps to reproduce the behavior:

  1. My migrations look like
IF NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pass' AND COLUMN_NAME = 'date_created')
BEGIN
    ALTER TABLE [pass]
        ADD date_created datetime NOT NULL DEFAULT (GETDATE());
END

IF NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pass' AND COLUMN_NAME = 'date_updated')
BEGIN
    ALTER TABLE [pass]
        ADD date_updated datetime NOT NULL DEFAULT (GETDATE());
END

UPDATE [pass]
    SET date_created = start_date, date_updated = start_date;
  1. I ran migrate with the following options
driver, err := sqlserver.WithInstance(conn.DB, &sqlserver.Config{})
if err != nil {
	log.Fatal("Failed to create migration driver: ", err.Error())
}

migrationsPath := fmt.Sprintf("file:///db_migrations"

m, err := migrate.NewWithDatabaseInstance(
	migrationsPath,
	"sqlserver",
	driver,
)
if err != nil {
	log.Fatal("Failed to create migrate instance: ", err.Error())
}
err = m.Migrate(CurrentDBVersion)
if err != nil {
	log.Fatal("Failed to execute migration: ", err.Error())
}
  1. See error
Failed to execute migration: migration failed: Invalid column name 'date_updated'. in line 14: IF NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pass' AND COLUMN_NAME = 'date_created')
BEGIN
    ALTER TABLE [pass]
        ADD date_created datetime NOT NULL DEFAULT (GETDATE());
END

IF NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pass' AND COLUMN_NAME = 'date_updated')
BEGIN
    ALTER TABLE [pass]
        ADD date_updated datetime NOT NULL DEFAULT (GETDATE());
END

UPDATE [pass]
    SET date_created = start_date, date_updated = start_date;

 (details: mssql: Invalid column name 'date_updated'.)

Expected Behavior
The three queries should run in a sequence, and the update query should execute successfully.
Note that, these queries run without errors in Azure Data Studio.
Also, if we add the update query in a separate migration, it runs without errors.

Migrate Version
v4.17.1-0.20240102204802-0d4158977486

Loaded Source Drivers
sqlserver

Loaded Database Drivers
sqlserver

Go Version
go version go1.22.3 linux/amd64

Stacktrace

  • NA -

Additional context

  • NA -
@sumit-anantwar
Copy link
Author

sumit-anantwar commented Aug 28, 2024

After some investigation, we found that the migrations are being executed inside an ExecContext

func (ss *SQLServer) Run(migration io.Reader) error {

And it seems that the ALTER TABLE changes aren't applied until the ExecContext block exits.
In which case, the new columns don't yet exist when the update is executed.

So, we tried to change the context for the update statement
Putting the update statement inside an SQL EXEC block did the trick.

EXEC('UPDATE pass SET date_created = start_date, date_updated = start_date')

Iit would be great if someone could confirm if this is the correct approach.

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

1 participant