I have migration in Postgres and SQLite, and I am facing problem with SQLite database. Same migrations are for 2 different databases. Postgres migration is OK, but not SQlite. I added migration for altering table and adding new field.
public function up()
{
Schema::table('retailer_products_photo_fix', function ($table) {
$table->integer('currency_id')->unsigned();
$table
->foreign('currency_id')
->references('id')
->on('currency')
->onUpdate('cascade')
->onDelete('cascade')
;
$table->dropColumn('currency');
});
}
But the following error was thrown:
General error: 1 Cannot add a NOT NULL column with default value NULL
When I try to add nullable() field isn't created and when I add default value 0 or 1 I got constraint error because in related table I have rows 1 and 2. How can this be solved?
Quoting from this answer by Daniel Vassallo:
SQLite doesn't support the ADD CONSTRAINT variant of the ALTER TABLE command
(The source that answer uses is here)
So attempting to alter your table by adding a foreign key constraint isn't going to work. You will need to:
Rename the table
Recreate the table with an updated structure (including your FK constraint)
Populate new table with existing data, providing values for new fields
Drop your old table
You can swap #1 and #2 so that you create a temporary version of your table, and then drop the old one / rename the new one at the very end, but that's up to you. It may be safer to go that route instead in case something goes wrong as you won't have your old table in a renamed state at that point.
Related
So I've been trying to write a migration that creates a data table question_display_formats using tiny increments as you see below.
And then, adding new Foreign Key column to existing questions table, trying to use the foreignIdFor method as a shortcut that'd look nice
public function up()
{
Schema::create('question_display_formats', function (Blueprint $table) {
$table->tinyIncrements('id');
$table->string('format');
});
Schema::table('questions', function (Blueprint $table) {
$table->foreignIdFor(QuestionDisplayFormat::class)
->nullable(true)
->after('question_type_id')
->constrained();
});
}
Turns out, this errors out with
General error: 1215 Cannot add foreign key constraint
Which turns out because the foreignIdFor users a different data type (confirmed by manually matching them and running the erroring out SQL alter table statement).
I googled, read and tried to adjust by doing:
$table->mediumIncrements('question_display_format_id'); before the foreignIdFor line, which leads to error
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name
'question_display_format_id' (SQL: alter table questions add
question_display_format_id mediumint un signed not null
auto_increment primary key, add question_display_format_id bigint
unsigned null after question_type_id)
Is there a way to use foreignIdFor with the matching column size? or am I supposed to fall back on the classic way of first creating the column explicitly, then doing like $table->foreign('question_display_format_id')->references('id')->on('question_display_formats'); which I don't like because its very verbose and doesn't look good?
On the other hand, this is a one time used script.. lol would've been faster to just do it the old way! but I am curious to see how to do it right :)
I am building an eCommerce site and I am running into an issue when migrating my orders table. I am getting the following error:
SQLSTATE[HY000]: General error: 3780 Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'orders_user_id_foreign' are incompatible. (SQL: alter table `orders` add constraint `orders_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete set null on update cascade)
The schema that sets up the foreign key for this migration looks like:
// set up foreign key on users
$table->integer('user_id')->unsigned()->nullable(); // will be null if guest
$table->foreign('user_id')
->references('id')->on('users')
->onUpdate('cascade')
->onDelete('set null');
I figured out that the users table schema sets up the id like so:
$table->id();
And the orders table schema sets up the id like this:
$table->increments('id');
So I changed the users migration so that it is the same as the orders migration i.e both are like:
$table->increments('id');
But when I run php artisan migrate, I get this back:
➜ MobileMastery_V2 git:(master) ✗ php artisan migrate --path=/database/migrations/2014_10_12_000000_create_users_table.php
Nothing to migrate.
As you can see above I tried declaring the path to the migration I wanted to see if that would work but it didn't. How can I get this single file to migrate? Thanks
Laravel migrations are intended to keep track of the changes you make on your database over time. Laravel creates a table called migrations that keeps track of the migrations if it already ran or not. So in this case you can create a new migration that only makes that change, or if your database has no data on it yet you can drop the database schema, make your modifications on the migrations and run it again.
And about the primary key and foreign keys, I recommend you to read this part of Laravel documentation.
You should create migration for this change and run php artisan migrate.
I am working in a project where a table has a foreign key called tax_id, the problem is that in some point another migration was created to change the tax_id to nullable.
Schema::table('products', function (Blueprint $table) {
$table->unsignedInteger('tax_id')->nullable()->change();
});
I realize this after I wrote other migrations and tried to run them, it throws Column 'tax_id' cannot be NOT NULL, it seems that in the "project" that migration was run, so I can't just delete the file, how can I run my migrations without the error? I have tried to remove the foreign key, but nothing worked.
I'll assume you're working with MySQL InnoDB because you did not specify the database type/engine.
You could try different approaches:
1) If yuo're in hurry, disable foreign keys, do the update, enable the foreign key. You should then correct the problem of course.
2) Add set tax_id to '' where tax_id is null and then do the migration
3) Document yourself about the database engine and implement a correct solution
Giacomo
This is my code:
public function up()
{
Schema::table('organization_user', function (Blueprint $table) {
$table->renameColumn('company_id', 'organization_id');
});
}
I want to rename column in table. And in this table have an column is enum type. But errors: Unknown database type company_roles requested, Doctrine\DBAL\Platforms\PostgreSQL100Platform may
not support it. I use laravel 5.6
This issue may be related to what is mentioned in Laravel Docs "You can't rename columns in the table that has 'enum' type". See:
I am afraid this is like 5 years old issue with Doctrine/DBal that Laravel uses see:[Bug] Schema builder - renameColumn fails on table with enum columns But one of the workarounds is also on the same issue report DB Query. For reference sake I'll put it here:
DB::statement("ALTER TABLE table_name MODIFY COLUMN column_name ENUM('Here','is','choices')");
In this case, you need to provide the right statement in the down() function of your migration class file to restore the state of the table.
I have a table with a simple structure (id, name and timestamps).
I need to add a slug but the system is already running and I need the slug in the database to be Unique and NOT NULL (therefore forbidding me to use a default value).
How I add a migration file to add this column and fill with with something similar to slug(name) in the Migration file ?
public function up() {
Schema::table('departments', function(Blueprint $table) {
$table->string('slug');
});
}
In your migration you may specify a default value for the column by doing:
// ...
$table->string('slug')->default('my-default-slug');
// ...
This will effectively set my-default-slug as value for every record that already exists inside departments at the time you run your migration. However, as far as I know does this setting not prevent modifications to any record where the slug is being set to an empty string afterwards. That's the whole thing with strings, an empty string is still a valid string to your database.
See the Laravel docs for more info on column modifiers.
EDIT
In response to the comment below, there is a fine package available for automatic slug generation based on another attribute of an Eloquent model.