'renameColumn migration fails for existing column with columns does not exist error
I get the error Doctrine\DBAL\Schema\SchemaException : There is no column with name 'price' on table 'class_rooms'.
while running migration to rename the price
column in class_rooms
table of my app. The table is created via a migration that runs before this renaming migration through a migration file named 2019_03_13_054619_create_class_rooms_table
with following code
class CreateClassRoomsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('class_rooms', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->uuid('yoga_style_id');
$table->date('start_date')->nullable();
$table->date('end_date')->nullable();
$table->time('duration_from')->nullable();
$table->time('duration_to')->nullable();
$table->string('name');
$table->bigInteger('price');
$table->longText('description')->nullable();
$table->string('image')->nullable();
$table->string('meta_title')->nullable();
$table->text('meta_description')->nullable();
$table->text('meta_keywords')->nullable();
$table->boolean('active')->default(true);
$table->softDeletes();
$table->timestamps();
$table->foreign('yoga_style_id')->references('id')->on('yoga_styles')
->onDelete('cascade');
}
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('class_rooms');
}
}
as you can see the price column is defined here. I have doctrine/dbal
installed and Laravel version I'm using is 5.7. The rename migration is as follows
class RenamePriceClassRoomsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('class_rooms', function (Blueprint $table) {
$table->renameColumn('price', 'cost_subscribed');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('class_rooms', function (Blueprint $table) {
//
});
}
}
The error I get is
Migrating: 2019_04_10_132923_rename_price_class_rooms_table
Doctrine\DBAL\Schema\SchemaException : There is no column with name 'price' on table 'class_rooms'.
at /Users/anadi/Code/new_web_app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php:82
78| * @return \Doctrine\DBAL\Schema\SchemaException
79| */
80| public static function columnDoesNotExist($columnName, $table)
81| {
> 82| return new self(
83| sprintf("There is no column with name '%s' on table '%s'.", $columnName, $table),
84| self::COLUMN_DOESNT_EXIST
85| );
86| }
Solution 1:[1]
There are some known issues with innoDB and biginteger column types. Looking at bug reports, it's not clear if they have fixed this. For example https://bugs.mysql.com/bug.php?id=15383
In your case, the column name is price
, it stands to reason that changing the column type to integer won't corrupt the existing values. In case, the column isn't part of a foreign key neither. This is a possible solution.
public function up()
{
Schema::table('class_rooms', function (Blueprint $table) {
$table->integer('price')->change();
$table->renameColumn('price', 'cost_subscribed');
// $table->bigInteger('price')->change(); //->optional
});
}
Solution 2:[2]
It seems the column is already renamed, you can check your table, but better way to do it is check the column exists or not before renaming it, if the column does not exists, you can just create a column with your desire name and type
class RenamePriceClassRoomsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasColumn('class_rooms', 'price')) {
Schema::table('class_rooms', function (Blueprint $table) {
$table->renameColumn('price', 'cost_subscribed');
});
} else {
Schema::table('class_rooms', function($table) {
$table->integer('price')->after('<some_column>');
});
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('class_rooms', function (Blueprint $table) {
//
});
}
}
or even choose to just add the column you want to add and delete the existing column if exists, but only if there is no data or you can use DB::raw() to copy the data from one column to another once the column is created and after it is done remove the column.
Schema::table('class_rooms', function($table) {
$table->integer('cost_subscribed')->after('<some_column>');
});
if (Schema::hasColumn('class_rooms', 'price')) {
Schema::table('class_rooms', function (Blueprint $table) {
$table->dropColumn('price');
});
}
There is a closed issue in mysql, that may be the cause of this issue, the issue describes as follows.
Updating a row on an updatable ResultSet with a BigInteger object on an UNSIGNED INT fails. A MysqlDataTruncation is throwned when updateRow() is executed.
and suggested an workaround: insert the value as a String, not only string using integer will also work. But as per current update with new commit have already fixed it, so it should not occur in new versions of mysql.
Solution 3:[3]
If you have tried migrating this before, but failed in the middle or if you have rolled this back before but not the create table migration, it is possible that you have already renamed the table since the function will not rename itself back to 'price'. However, it is not for sure as I don't have the information of what migrations you ran before this.
Solution 4:[4]
First check in your class_rooms has price column. if you have that column then as per documentation you have to install doctrine/dbal package
composer require doctrine/dbal
Then try
class RenamePriceClassRoomsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('class_rooms', function (Blueprint $table) {
$table->renameColumn('price', 'cost_subscribed');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('class_rooms', function (Blueprint $table) {
$table->renameColumn('cost_subscribed','price');
});
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dimitri Mostrey |
Solution 2 | |
Solution 3 | ITO |
Solution 4 | Hamelraj |