PHPUnit doesn't seem to be running Laravel Migration - php

I've got an issue where I'm running some tests in laravel 5.4 via phpunit
I'm using an in memory sqlite database for testing
I've got a test class which i've removed bunch of other stuff from so it effectively looks like
<?php
namespace Tests\Unit;
use App\User;
use App\Order;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class OrderTest extends TestCase
{
use DatabaseMigrations;
/** #test */
function can_update_status()
{
// This is empty, it fails on this test because its alphabetically the first test in the whole suite.
}
}
I've recently created a new migration which adds the "paid" column
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddStatusToOrders extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('completed');
$table->boolean('paid')->default(0);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('completed')->default(0);
$table->dropColumn('paid');
});
}
}
However whenever I run this test I get an error saying the paid column doesn't exist - even after a composer du
PHPUnit 6.0.7 by Sebastian Bergmann and contributors.
...................................E
Time: 10.69 seconds, Memory: 46.00MB
There was 1 error:
1) Tests\Unit\OrderTest::can_mark_as_paid
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such column: paid (SQL: update "orders" set "paid" = 1, "updated_at" = 2017-04-05 15:27:11 where "id" = 1)
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:647
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Caused by
Doctrine\DBAL\Driver\PDOException: SQLSTATE[HY000]: General error: 1 no such column: paid
/Users/owen/Sites/1st-choice-spares/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:79
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:470
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:640
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Caused by
PDOException: SQLSTATE[HY000]: General error: 1 no such column: paid
/Users/owen/Sites/1st-choice-spares/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:77
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:470
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:640
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Does anybody have any ideas why this would be happening, and how I can resolve it? It might be worth adding I've tried changing the column names etc and the same issue is happening with that
Thanks
UPDATE
If I comment out the lines in the down migration e.g $table->dropColumn('paid');
Then it continues to run - however I'm struggling to understand why the down method would be running before the up has been run?
Update 2
It seems the above finding was due to the column not getting created in the first place, if i suppress that error, the original error appears that the column doesn't exist - which suggests the migration failed to create it.

According to laravel documentation
Dropping or modifying multiple columns within a single migration while using a SQLite database is not supported.
And although you not trying to modify or drop multiple columns ,you are trying to drop and create in one single migration and in both cases ALTER TABLE query is executed ,and the problem here is the limitations of ALTER TABLE query of sqlite .
You can separate each statement like this:
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('completed');
});
Schema::table('orders', function (Blueprint $table) {
$table->boolean('paid')->default(0);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('completed')->default(0);
});
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('paid');
});
}

Related

How can I modify DB structure in Laravel without truncating tables?

I have defined a DB table structure below.
If I want to modify a table column:
From
$table->string('active',1);
To:
$table->string('active',1)->nullable(); // allow null values
Every time I run the migration script, my tables will be truncated.
Is there a way to define a table structure and have it be modified to correct structure WITHOUT dropping the table?
Here is my code for now:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class VTUser extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('Z_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nickname')->unique();
$table->string('email')->unique();
$table->string('passhash');
$table->string('keygen');
$table->string('active',1)->nullable();
$table->string('banned',1);
$table->string('admin',1);
$table->string('step',1);
// $table->rememberToken();
// $table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('Z_user');
}
}
There can be two ways of achieving this -
Either you can rollback the migration with php artisan migrate:rollback --step=1 and then change the up function with $table->string('active',1)->nullable();
Create a new migration to update the table by doing $table->string('active',1)->nullable(); in this new migration.

Php artisan migrate gives different result with the same code

pic1
pic2
Pic 2 is the usual laravel migration tables that i created. Pic 1 is the laravel migration tables that i newly created. They have the same code with same foreign key only with different attributes name. Why is pic 1 only have varchar(191) instead of varchar(255), and the foreign key doesnt apply from migrations anymore? Before pic 1, i did ran some stuff on terminal for deployment purpose like npm build. Is the terminal the cause of this?
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::create('calibrations', function (Blueprint $table) {
$table->id();
$table->string('Identification_No');
$table->foreign('Identification_No')->references('Identification_No')->on('fieldequips');
$table->string('Calibration_point');
$table->date('Expired_Date');
$table->date('Calibration_Date');
$table->date('Next_Due_Date');
$table->string('Correction_factor');
$table->string('Validated_by');
$table->date('Validated_Date');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('calibrations');
}
};
In app/Providers/AppServiceProvider.php you should change Schema::defaultStringLength(191) to Schema::defaultStringLength(255), I guess

Laravel: Cannot add foreign keys constraints on production

I’m developing a Laravel project and I created the models, when I run the migrations on my computer (where I’m developing) everything works fine, even the relations between tables. The problem comes when I upload the code to the production server and when I run the migrations where I create the relations, I got an error.
In the code below I leave some commented lines, those lines are things that I tried to do to solve the problem, but nothing worked.
I tried to set the table engine to innoDB on both tables, but it didn’t work.
I tried to set the id datatype as increments on both tables, and the column deviceTypeID that is going to serve as foreign key, I defined it as unsigned and integer and it didn’t work.
I even checked the PHP, Composer, Doctrine/dbal and mysql versions on both computers and are the same (or almosr the same).
Developing Computer:
PHP: 7.3
Composer: 1.8.6
MySQL Server: 5.7.23
Doctrine/dbal: 2.9
Production Server:
PHP: 7.3
Composer: 1.9
MySQL Server: 5.7.25
Doctrine/dbal: 2.9
(It runs Ubuntu Server 18.04)
I also tried to run the project on another computer an see if I got the same error, but it didn't come, everything worked fine.
I also ran this query "alter table devices add constraint devices_devicetypeid_foreign foreign key (deviceTypeID) references devicestype(id) on delete cascade" without all the quotes directly on mysql command line and it worked. So the problem is not related to the user privileges.
It always crash on production when it tries to run the code on AddRelationDevicesDeviceType
class CreateDevicesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('devices', function (Blueprint $table) {
//$table->engine = 'innoDB'
$table->bigIncrements('id');
//$table->increments('id');
$table->unsignedBigInteger('deviceTypeID');
//$table->integer('deviceTypeID')->unsigned();
$table->timestamps();
});
}
}
class CreateDevicesTypeTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('devicesType', function (Blueprint $table) {
//$table->engine = 'innoDB'
$table->bigIncrements('id');
//$table->increments('id');
$table->string("Device Type");
$table->text("Description");
$table->timestamps();
});
}
}
class AddRelationDevicesDeviceType extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('devices', function($table) {
$table->foreign('deviceTypeID')
->references('id')->on('devicesType')
->onDelete('cascade');
});
}
}
This is the error:
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `devices` add constraint `devices_devicetypeid_foreign` foreign key (`deviceTypeID`) references `devicestype`(`id`) on delete cascade) at /var/www/html/MYPROJECT/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
660| // If an exception occurs when attempting to run a query, we'll format the error
661| // message to include the bindings with SQL, which will make this exception a
662| // lot more helpful to the developer instead of just the databa se's errors.
663| catch (Exception $e) {
> 664| throw new QueryException(
665| $query, $this->prepareBindings($bindings), $e
666| );
667| }
668|
Exception trace:
1 Doctrine\DBAL\Driver\PDOException::("SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint") /var/www/html/MYPROJECT/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:119
2 PDOException::("SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint") /var/www/html/MYPROJECT/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117
I I figured out how to solve my problem.
The problem was when I ran the first migration where I create the table “devicesType” MySQL changed the table name to lower case, so it ended up being “devicestype” and when I tried to refer that table in the last migration where I create the relation Laravel couldn’t find the table.
My development server wasn’t case sensitive while my production server was case sensituve.
I also change the "deviceTypeID" from "unsignedBigInteger" to "bigInteger" and I specify the the type unsigned using the method "unsigned"
This is my new code if is useful to someone:
class CreateDevicesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('devices', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('deviceTypeID')->unsigned();
$table->timestamps();
});
}
}
class CreateDevicesTypeTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('devicestype', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string("Device Type");
$table->text("Description");
$table->timestamps();
});
}
}
class AddRelationDevicesDeviceType extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('devices', function($table) {
$table->foreign('deviceTypeID')
->references('id')->on('devicestype')
->onDelete('cascade');
});
}
}

How to drop schema with connection to table in another database?

In my Laravel app, I have connections to different databases and when I need to fresh my tables in each of database with a new dummy data (I do it with php artisan migrate:fresh --seed command) I always have this error
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'table_name' already exists
which is weird because I have down() method in my migration class
class CreateExampleTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::connection('conn2')->create('table_name', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::connection('conn2')->dropIfExists('table_name');
}
}
If you use migrate:refresh instead of fresh it will rollback the database using your down() methods.
I think the problem is not in your down() but with your up() : it is trying to create a table, but a table with that name already exists.
I would suggest doing something like:
if (!Schema::hasTable('tbl_name')) {
// create table
}
You may also have to specify which database you are using in the migrations.

Updating Existing Column Attributes - Laravel 5 Migration

I have
a existing column called cpe_mac. I created it via migration like this :
$table->string('cpe_mac')->default(NULL)->nullable();
I want
I want to add this ->unique() to that column, without having to drop it and re-add.
I've tried
$table->string('cpe_mac')->unique();
Migration File
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterCaptivePortalTable212017 extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->unique();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->default(NULL)->nullable();
});
}
}
I kept
getting
SQLSTATE[42701]: Duplicate column: 7 ERROR: column "cpe_mac" of relation "captive_portals" already exists
Is there a way to achieve this without having to drop my existing column? I have a lot client data that can't be deleted.
Schema::table('users', function (Blueprint $table) {
$table->string('cpe_mac')->unique()->change();
});
https://laravel.com/docs/5.0/schema#changing-columns
You need to use change() method:
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->unique()->change();
});
Alternatively, you may create the index after defining the column. For example:
$table->unique('email');
https://laravel.com/docs/5.4/migrations#indexes
I had the same issue and this is the solution for Laravel 5.6:
Step1: run this command: composer require doctrine/dbal
step2:run this command:php artisan make:migration THE
-NAME_YOU_WANT --table=TABLENAME
step3: in the added migration, add $table->string('cpe_mac')->unique()->change(); in Schema::table part.
step4: run this command: php artisan migrate
If the column is already defined you can use:
$table->unique('cpe_mac');

Categories