My Laravel migration keeps getting error when reset/refresh:
ORA-01758: table must be empty to add mandatory (NOT NULL)
The migration is as follow:
public function up()
{
Schema::table('kasbank', function (Blueprint $table) {
$table->dropColumn('name_bn');
$table->dropColumn('id_rekon');
$table->string('name_kb')->after('kode');
$table->integer('id_rek')->nullable();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('kasbank', function (Blueprint $table) {
$table->dropColumn('id_rek');
$table->dropColumn('name_kb');
$table->integer('id_rekon')->nullable();
$table->string('name_bn')->after('kode');
});
}
FYI, column id_rekon is initially nullable in the database.
What's missed from my migration?
The problem is that your table is not empty and the current rows will be given NULL as a default value, but the column is not allowed to be NULL.
You should be able to get around it by setting a default value.
From the Oracle docs:
However, a column with a NOT NULL constraint can be added to an
existing table if you give a default value; otherwise, an exception is
thrown when the ALTER TABLE statement is executed.
Try:
$table->integer('id_rek')->default($value)->nullable();
From: https://laravel.com/docs/5.5/migrations
Related
I have already checked the other topics but no solution worked with me. I tried the last time:
public function up()
{
if(Schema::hasColumn('orders_products_variations','id')) {
Schema::table('orders_products_variations',function (Blueprint $table) {
$table->unsignedInteger('id')->change();
$table->dropPrimary();
$table->dropColumn('id');
});
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('clients', function (Blueprint $table) {
$table->string('id');
});
}
And the error message is :
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key (SQL: alter table orders_products_variations drop primary key)
Any idea?
A migration class contains two methods: up and down. The up method is
used to add new tables, columns, or indexes to your database, while
the down method should reverse the operations performed by the up
method.
Dropping Columns
To drop a column, use the dropColumn on the Schema builder inside down method
if (Schema::hasColumn('table_name', 'column_name')) {
Schema::table('table_name', function (Blueprint $table) {
$table->dropColumn('column_name');
});
}
Adding / Dropping Columns
PS When you have to add a new column to the existing table in Laravel, you must
create new migration .
php artisan make:migration add_column_to_table
I have a questions table in my database, in which I have a column of question_title, now I have added a column question_slug, which will contain the question's slug URL, so how I set question_slug default value as question_title in Laravel Migration, I need this all because I have questions saved in the database so I have run php artisan make:migration add_column_to_questions --table=questions now I have this code:
Schema::table('questions', function (Blueprint $table) {
$table->string('question_slug')->default();
});
first of all, create a new migration and put this code within it:
connections_string : it's within web/config/database.php file
configuration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class NameOfUrMigration extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('questions', function (Blueprint $table) {
$table->string('question_slug')->default();
});
$questions = DB::connection('connections_string')->table('questions')->get();
foreach($questions as $question)
{
$question->question_slug = str_slug($question->question_title);
$question->save();
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
}
}
According to the documentation, default() is used to Declare a default value for a column.
That means the value that gets inserted by default in a field if you do not provide a value for it in the insert query.
The default() cannot help you achieve what you need here.
What you could do is create a new migration class with a raw query in the up() method which will update the value of question_slug with the value of question_title.
something like this:
public function up()
{
$sql = "UPDATE `questions` SET `question_slug` = `question_title` WHERE 1;";
//add filtering conditions if you don't want ALL records updated
DB::connection()->getPdo()->exec($sql);
}
Make sure you also create a corresponding down() method for the rollback
Trying to change data column type to tinyInteger in a Laravel 5.2 migration:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterTableNameTableChangeNotificationSentTinyint extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('table_name', function ($table) {
$table->tinyInteger('column_name')->default(0)->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
}
}
I'm getting an error:
Doctrine\DBAL\DBALException]
Unknown column type "tinyinteger" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the known types wit
h \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database introspection then you might have forgot to register all database types for a Doctrine Type. Use Abstrac
tPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot so
me mapping information.
Am I doing something wrong?
Indeed Doctrine Dbal does not support tinyint you can read from their doc here
Unfortunately as well, laravel stated that tinyint cannot be changed. Check here
I need someone to prove this as wrong, because I had to use smallInteger because of this issue for one of my projects. I am thinking maybe boolean() might be the solution. I have not tried this though.
i hope that this will solve your issue
DB::statement("ALTER TABLE table_name CHANGE COLUMN column_name column_name TINYINT UNSIGNED NOT NULL");
Do This
Change tinyInteger to smallInteger
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\SmallIntType;
if (!Type::hasType('integer')) {
Type::addType('integer', SmallIntType::class);
}
I got same problem and found this solution. It worked for me. But it raise in me a question that why creator don't update to doctrine/dbal package. Maybe this solution can cause errors in some case? Hope someone explain in this answer.
Can you use boolean?
or
$table->smallInteger('column_name')->tinyInteger('column_name')->unsigned()->change();
If you are trying to convert a non-numeric column to an int column, you will get this error. The values cannot be converted.
You might run into this when converting an old string value to an id reference to a parent table.
Instead of trying to change the existing column, create a new column and delete the old:
// Add new int column
Schema::table('children', function (Blueprint $table) {
$table->unsignedTinyInteger('parent_id')->after('parent_slug');
});
// Convert old values to new
// Only runs on environments that already have data in db, by virtue of pulling all records from the parents table
foreach (\App\Parents::all() as $parent) {
\App\Child::where('parent_slug', $parent->slug)->each(function ($child) use ($parent) {
$child->update([ 'parent_id' => $parent->id ]);
});
}
// Drop old string column
Schema::table('children', function (Blueprint $table) {
$table->dropColumn('parent_slug');
});
!!! This solution is only for empty tables. Not if already populated.
Just drop and recreate the column with same name.
public function up()
{
// Drop and recreate because laravel don't allow to change to the tinyInteger type
Schema::table('your_table_name', function (Blueprint $table) {
$table->dropColumn(['rating']);
});
Schema::table('your_table_name', function (Blueprint $table) {
$table->tinyInteger('rating')->nullable()->after('some_column_name');
});
}
According to this https://github.com/laravel/framework/issues/8840 "BOOL" and "BOOLEAN" are both synonymous to "TINYINT" therefor just use "boolean" method instead of "tinyInteger", its the same in Laravel.
try this
Schema::table('table_name', function (Blueprint $table) {
$table->tinyInteger('column_name')->default(0)->change();
here is the issue. I am banging my head for hours now on this. Laravel is not allowing me to have a primary key (it says multiple but you can see it has only one). And further more as there is issue causing in primary key in teachers table. I am not able to use this as a foreign key in courses table.
Migration file for teacher table
class CreateTeachersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('teachers', function (Blueprint $table) {
$table->increments('teacher_id')->primary();
$table->string('email', 200);
$table->string('first_name',300)->nullable();
$table->string('last_name',300)->nullable();
$table->string('account_status',50)->default('inactive');
$table->string('subscription_status',50);
$table->string('account_reset_code',400)->nullable();
$table->string('passkey',500);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('teachers');
}
}
Migration File for courses table
class CreateCoursesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('courses', function (Blueprint $table) {
$table->increments('course_id')->primary();
$table->integer('teacher_id_fr');
$table->string('course_name', 500);
$table->string('course_code',300);
$table->string('subject_area',300);
$table->string('course_level',100);;
$table->string('grade_periods',100);
$table->timestamps();
});
Schema::table('courses',function(Blueprint $table){
$table->foreign('teacher_id_fr')->references('teacher_id')->on('teachers')->onDelete('cascade')->onUpdate('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('courses');
}
}
Issue raised on migrating
Syntax Error or access violation. 1068 Multiple primary keys found
.
What I've tried by now
1) Making the primary column unsigned using unsigned method.
2) using InnnoDB engine type for table.
3) And much other things as suggested for similiar posts on the forums but nothing seems to work for me.
EDIT
I've removed the primary() method from both files at $table->increments('teacher_id'). As this is said Laravel marks auto increments columns as primary keys.
But now the error is on courses table as it says.
General error : 1215 cannot add foreign key constraint
You can define Multiple primanry key in migration file as below:
$table->primary(array('field_name1', 'field_name2'));
Try to replace this, remove primary(), increments automatically creates it primary
$table->increments('teacher_id')->primary();
to
$table->increments('teacher_id');
For new error try this General error : 1215 cannot add foreign key constraint
public function up()
{
Schema::create('courses', function (Blueprint $table) {
$table->increments('course_id');
$table->integer('teacher_id_fr');
$table->string('course_name', 500);
$table->string('course_code',300);
$table->string('subject_area',300);
$table->string('course_level',100);;
$table->string('grade_periods',100);
$table->timestamps();
$table->foreign('teacher_id_fr')
->references('teacher_id')->on('teachers')
->onDelete('cascade')
->onUpdate('cascade');
});
}
I was able to fix the issue with a minute change. I modified courses migration file like below and it worked like a charm
$table -> integer('teacher_id_fr') -> unsigned();
Reason
Actually both the referenced and referencing columns (teacher.teacher_id and course.teacher_id_fr in this case) must be of same type.
Having said that, Laravel marks autoincrement columns as "Primary" and of type unsigned. So make sure to change foregin key column to match the type of primary key i.e unsigned. which the above modification does.
Hope it clarifies the issue and solution. If you have anything else on your mind. Please give it a shot here.
Happy Learning!
I've created a table using migration like this:
public function up()
{
Schema::create('despatch_discrepancies', function($table) {
$table->increments('id')->unsigned();
$table->integer('pick_id')->unsigned();
$table->foreign('pick_id')->references('id')->on('picks');
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->integer('original_qty')->unsigned();
$table->integer('shipped_qty')->unsigned();
});
}
public function down()
{
Schema::drop('despatch_discrepancies');
}
I need to change this table and drop the foreign key reference & column pick_detail_id and add a new varchar column called sku after pick_id column.
So, I've created another migration, which looks like this:
public function up()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->dropForeign('pick_detail_id');
$table->dropColumn('pick_detail_id');
$table->string('sku', 20)->after('pick_id');
});
}
public function down()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->dropColumn('sku');
});
}
When I run this migration, I get the following error:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1025 Error on rename of
'./dev_iwms_reboot/despatch_discrepancies' to
'./dev_iwms_reboot/#sql2-67c-17c464' (errno: 152) (SQL: alter table
despatch_discrepancies drop foreign key pick_detail_id)
[PDOException]
SQLSTATE[HY000]: General error: 1025 Error on rename of
'./dev_iwms_reboot/despatch_discrepancies' to
'./dev_iwms_reboot/#sql2-67c-17c464' (errno: 152)
When I try to reverse this migration by running php artisan migrate:rollback command, I get a Rolled back message, but it's not actually doing anything in the database.
Any idea what might be wrong? How do you drop a column that has a foreign key reference?
You can use this:
Schema::table('despatch_discrepancies', function (Blueprint $table) {
$table->dropForeign(['pick_detail_id']);
$table->dropColumn('pick_detail_id');
});
If you take a peak at dropForeign source, it will build the foreign key index name for you if you pass the column name as an array.
It turns out; when you create a foreign key like this:
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
Laravel uniquely names the foreign key reference like this:
<table_name>_<foreign_table_name>_<column_name>_foreign
despatch_discrepancies_pick_detail_id_foreign (in my case)
Therefore, when you want to drop a column with foreign key reference, you have to do it like this:
$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign');
$table->dropColumn('pick_detail_id');
Update:
Laravel 4.2+ introduces a new naming convention:
<table_name>_<column_name>_foreign
Update:
Larave > 8.x introduces a new function
dropConstrainedForeignId('pick_detail_id');
This will delete the column as well as the foreign key of the column
I had multiple foreign keys in my table and then I had to remove foreign key constraints one by one by passing column name as index of the array in down method:
public function up()
{
Schema::table('offices', function (Blueprint $table) {
$table->unsignedInteger('country_id')->nullable();
$table->foreign('country_id')
->references('id')
->on('countries')
->onDelete('cascade');
$table->unsignedInteger('stateprovince_id')->nullable();
$table->foreign('stateprovince_id')
->references('id')
->on('stateprovince')
->onDelete('cascade');
$table->unsignedInteger('city_id')->nullable();
$table->foreign('city_id')
->references('id')
->on('cities')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('offices', function (Blueprint $table) {
$table->dropForeign(['country_id']);
$table->dropForeign(['stateprovince_id']);
$table->dropForeign(['city_id']);
$table->dropColumn(['country_id','stateprovince_id','city_id']);
});
}
Using below statement does not work
$table->dropForeign(['country_id','stateprovince_id','city_id']);
Because dropForeign does not consider them seperate columns that we want to remove. So we have to drop them one by one.
The key (for me) to solving this was to make sure that the $table->dropForeign() command was being passed the right relationship name, not necessarily the column name. You do not want to pass the column name, as would be much more intuitive IMHO.
What worked for me was:
$table->dropForeign('local_table_foreign_id_foreign');
$table->column('foreign_id');
So the string I passed to dropForeign() that worked for me was in the format of:
[local table]_[foreign key field]_foreign
If you have access to a tool like Sequel Pro or Navicat, being able to visualize those will be very helpful.
Something that occurred to me was that I didn't know where to put the Schema::table block.
Later I discovered that the key is on the SQL error:
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table if exists `lu_benefits_categories`)
So the Schema::table block needs to go in the down() function of the lu_benefits_categories migration and before the Schema::dropIfExists line:
public function down()
{
Schema::table('table', function (Blueprint $table) {
$table->dropForeign('table_category_id_foreign');
$table->dropColumn('category_id');
});
Schema::dropIfExists('lu_benefits_categories');
}
After that, the php artisan migrate:refresh or php artisan migrate:reset will do the trick.
on laravel 8 use dropConstrainedForeignId
(https://github.com/laravel/framework/pull/34806)
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAddressFieldsInEventTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('events', function (Blueprint $table) {
$table->bigInteger('address_id')->nullable();
$table->foreign('address_id')
->references('id')
->on('addresses')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('events', function (Blueprint $table) {
$table->dropConstrainedForeignId('address_id');
$table->dropColumn('address_id');
});
}
}
You can disable relation id first
Schema::disableForeignKeyConstraints();
In Laravel > 8.x you can use the following code to add/remove foreign keys. You will need to drop the foreign key before dropping the column, as otherwise, the foreign key could cause the error your encountering.
Add foreign key
$table->foreignId('pick_id')->constrained('picks')->cascadeOnUpdate()
->cascadeOnDelete();
Drop foreign key
$table->dropConstrainedForeignId('pick_id');