-
Notifications
You must be signed in to change notification settings - Fork 11.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
[6.x] Fix laravel migrations when migrating to sql server (dropColumn with default value) #31229
[6.x] Fix laravel migrations when migrating to sql server (dropColumn with default value) #31229
Conversation
…elharkes/framework into 5.8-fix-sqlserver-drop-column
I faced the same issue today. Really hope they will merge your fix! |
I have the same problem. |
I'll see to find time to make laravel tests for SQL server (which are currently missing) using the SQL server Development Docker image. to test these cases, sorry for the inconvenience guys. |
@heartbeatLV i'm testing this now can you please provide a small piece reproducable piece of code so i can unit test this? |
public function up() {
// check schema exists
// SELECT * FROM sys.schemas WHERE name = 'example'
DB::statement('CREATE SCHEMA example');
Schema::create('example.tests', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::table('example.tests', function (Blueprint $table) {
$table->boolean('testBool')->default(false);
});
Schema::table('example.tests', function (Blueprint $table) {
$table->dropColumn('testBool');
});
}
public function down() {
// this will not work because the "existing" check fails
// Schema::dropIfExists('example.tests');
// SQL: if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'example.tests') drop table "example"."tests"
// workaround
DB::statement('DROP TABLE IF EXISTS example.tests');
DB::statement('DROP SCHEMA IF EXISTS example');
} hope it helps |
Thanks this is perfect, im testing now. hope to finalize a PR coming week into laravel :) |
@heartbeatLV it will be fixed in next version of laravel once my PR gets merged: #32957 |
Currently when running the following script would work in
mysql
(and mariadb) but would fail insqlserver
.this would throw error:
[Illuminate\Database\QueryException] SQLSTATE[42000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]The object 'DF__foo__bar__322242A7' is dependent on column 'bar'. (SQL: alter table "foo" drop column "bar")
The problem: on
dropColumn()
your fluent code doesn't know if the column had a default constraint. This code added would retrieve wether a default constraint exists on dropped columns and remove them before dropping the column as well, and thus not triggering ais dependent on column
constraint QueryException.This solution
Creates a script before drop column is called to get the Default Constraints and drop these before the column is dropped.
In this case it would run script:
Which creates the following sql and executes it:
Before running sql
End result
migrating from mysql to sqlserver becomes almost seamless, no need to specify dropping default constraints manually like proposed in other issues like: #4402
Tests
I couldn't create e2e tests because this laravel travis setup has no sql server?
But locally this fix has worked great for me.