So I have database with table, where I need to edit one column, make it nullable, to be specific. How can I access it from php artisan tinker, or maybe somehow re-run migration on one table without losing data from it?
With tinker you cannot modify schema table. You need to create a migration like this:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterTableUsers extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('users', function ($table) {
$table->string('name', 50)->nullable()->default(null)->change();
});
}
}
In this case, we make name nullable with default value null.
More info: https://laravel.com/docs/master/migrations#modifying-columns
You can just run the suggested code:
Schema::table('users', function ($table) {
$table->string('name', 50)->nullable()->default(null)->change();
});
directly from tinker
If you want to re-run migration or add new migration that alters the existing table depends on whether you are coding on production mode or development mode. Generally on development mode re-running migration may be best option(due to dummy data)..On other hand; on production mode, if the data is important ..we generally add the new migration that updates the existing table (because data may be important to us..)
Related
I'm developing a web using Laravel 9. I used the command sail php make:migration add_bought_to_products_table to add a boolean column called "bought" in a products table. When trying to modify the value using Eloquent helpers (Product::where('id', $product->id)->update(array('bought'=>true)) the value is not updated in the database. When looking at it, I se that the new field "bought" created by the migration is marked as Read-only: No corresponding table column.
The migration code is the following:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('products', function (Blueprint $table) {
$table->boolean('bought');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('products', function (Blueprint $table) {
$table->dropColumn('bought');
});
}
};
Here a screenshot of the database:
I have already tried to clean the cache and rebuild many times the database doing a rollback and migrating again. The curious thing is that I previously added the field "visibility" which works perfectly with the exact same code and steps as the field that is giving the problem.
How can I solve it?
After breaking my head a lot, I solved it by simply doing a clean restart of the docker containers. It seems that the issue had nothing to do with Laravel but with Docker!
For anyone experiencing similar issues: make sure to end Docker and all containers and do a clean restart.
I simply restarted my database tool and it was gone.
I have an old migration where I used the foreignIdFor() method to create a column.
I later decided to delete the model which was referenced and now, when I do a migrate:refresh locally, that migration triggers an error saying that the model doesn't exist, of course.
So, should one never delete models referenced with foreignIdFor() and use unsignedBigInteger()instead ?
EDIT:
I know foreignIdFor and unsignedBigInteger will create the same column. When I say I deleted the model, I mean the model class, not a model.
My migration file :
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Models\Event;
use App\Models\OutlookCategory;
class CreateEventOutlookCategoryTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('event_outlook_category', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Event::class);
$table->foreignIdFor(OutlookCategory::class);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('event_outlook_category');
}
}
The foreignIdFor method adds a {column}_id UNSIGNED BIGINT equivalent column for a given model class, so using unsignedBigInteger() doesn't make any difference.
Resources:
https://laravel.com/docs/9.x/migrations#column-method-foreignIdFor
https://laravel.com/docs/9.x/migrations#column-method-unsignedBigInteger
What you could/needed to do is to add cascade delete, and make sure that whenever associated model is deleted, all related models are deleted too.
You could do it like this:
table->foreignId('column_name_id')
->constrained()
->onDelete('cascade');
Resources:
https://laravel.com/docs/9.x/migrations#foreign-key-constraints
Answer to the edit:
If you delete Model that was used in foreignIdFor, that method will not be able to understand what you are referencing, and therefore it will fail. So, the answer to your question is YES and NO.
Let me elaborate. If your migrations will be run just once, on the production environment, for example, then you will be able to delete the model you've been referencing in the previous migrations and just create a new migration that will cleanup those columns.
In all other cases, when your migrations will be run for a few times (locally when you use migrate:fresh), you need to have Model that was referenced in them in your code base in order for it to work properly.
If you want to avoid these kind of problems that you are experiencing right now, just use unsignedBigInteger and pass to it string that is the name of the column, and you don't have to worry about deleting the model. However, you will still need to pay attention not to delete the column that is referenced there, because you will get another error for missing column.
My laravel 5.4 app contain complex database structure with many relations, so I'm willing to know it is ok to use Schema::enableForeignKeyConstraints(); and Schema::disableForeignKeyConstraints(); in down() function. Because if I run command php artisan migrate:reset then there are relations and delete is not possible...
Complete example:
public function down()
{
Schema::disableForeignKeyConstraints();
Schema::drop('blog');
Schema::enableForeignKeyConstraints();
}
As described is this recommended to use because of Database functionality?
Normally you would migrate your databases in a special order so there are no conflicts with foreign keys, e.g.
Create:
users
permissions
user_permission
When you want to do a rollback the best way is to reverse all your actions, so you start
Delete:
user_permission
permissions
users
A common mistake is this example:
class User extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username')->nullable()->unique();
$table->timestamps();
});
Schema::create('user_permission', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->integer('permission_id')->unsigned();
$table->foreign('permission_id')->references('id')->on('permissions');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users'); // error will be thrown, because user_permission still exists.
Schema::dropIfExists('user_permission');
}
}
Of course you could use disableForeignKeyConstraints, but in my opinion it's a kind of dirty solution and you should follow the same way you migrated your tables (same way = don't disable foreign keys).
This is a valid use case. This has been a big issue with laravel migrations from a long time. You need to make sure the order of drop tables works in such a way that it drops the related tables first before dropping the parent table. This can become very tedious with large number of migrations. Therefore forcing to disable foreign key constraints before dropping is valid. Although you need to be careful since you can drop individual migrations with existing relationship by mistake. This can cause big problems.
Laravel 5.5 is coming with a new command migrate:fresh. This would help with cleaning the database before migrating again unlike the existing migrate:reset or migrate:refresh which causes foreign key issues.
I'm new to using Laravel.
I have a .sql file where created a whole bunch of tables("CREATE TABLE my_table......."). Is there a way to somehow import these statements into Laravel? I could always manually rewrite these tables in raw php, but I feel that this would take too long and there is possibly an easier way to do it.
You would use migrations in Laravel to do this for example
I want to create a table called tasks I would use this command in artisan
php artisan make:model Task
This would create a model called task and a migration for this table.
You can then access the migration file and input something like this
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTasksTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('task_id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('tasks');
}
}
You would then run the artisan command to create this table
php artisan migrate
This then automatically creates your table.
Its a very useful feature and you can also rollback your migrations or even refesh it meaning it will remove the table and then reinstate it with no data in.
php artisan migrate:refresh
link to the docs
http://laravel.com/docs/5.1/migrations
I'm growing desperate, I need help! I've been at this all day!
I want to configure a DB in Laravel. I have all my migrations (in order) so no foreign key will conflict and hit a table that would only be created later.
But no matter what I try I keep hitting an error that says this,
http://prntscr.com/6z23nw
EDIT: now it says the exact same thing but that the class was 'not found'... I'm totally clueless here....
A bit more information, (I was going to post a screenshot but I can't)... searching for usages of GroupUser all I can find is the one I posted and entries in the laravel.log (listed as non-code usage). So there really is no other "groupUser" class
Here's a screenshot of my migrations folder.
These are my migrations they run in order and all tables until GroupUser are properly created
the migration that's causing all this mess
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class GroupUser extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('group_user', function(Blueprint $table)
{
$table->integer('user_id')->unsigned();
$table->integer('group_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('group_id')->references('id')->on('groups');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('group_user');
}}
One final note I completely erased all the previous migrations and even tried reinstalling with the php artisan migrate:install
Run composer dump-autoload. After creating the migration files via artisan, you need to re-run composer to have them be autoloaded automatically.
Solved the issue,
. migrate:reset to set everything from blank
. created migrations with the tables but no foreign keys and dependencies
. php artisan migrate (all worked out fine)
. created new migrations altering the tables required with the foreign keys.
. again 'php artisan migrate'
I think it all worked fine. Thank you for your help and ideas everyone!