Change the datatype in the column with data in laravel migration - laravel

This is the migration? i have to change the string data column into integer data column with existing data
public function up()
{
Schema::table('SYS_tenants' ,function (Blueprint $table){
$table->integer('tena_type')->unsigned()->nullable()->change();
$table->foreign('tena_type')->references('id')->on('account_types');
});
}

As per laravel Documentation you can create a new migration and do it like this:
Schema::table('SYS_tenants', function (Blueprint $table) {
$table->integer('tena_type')->unsigned()->nullable()->change();
});
Before modifying a column, be sure to add the doctrine/dbal dependency
to your composer.json file.
composer require doctrine/dbal
Reference: Laravel -> Database: Migrations-> Modifying Columns

You can use change method on the field which you want to change the type after setting the new field type.
public function up() {
Schema::table('SYS_tenants' ,function (Blueprint $table){
$table->string('tena_type')->change();
});
}
I supposed the migration which create the table has already call all requirement you need like unique, nullable and so on. You can call change method, by the way there isn't restriction about any modification you want to perform like add other mysql index on that field.
Do not forget to add doctrine/dbal in composer.json file

Migrations#Modifying Columns
Looks like what you have should work:
Schema::table('SYS_tenants' ,function (Blueprint $table){
$table->integer('tena_type')->unsigned()->nullable()->change();
});
Depending on your database you may need to cast the values to the new type: (for mysql: https://www.mysqltutorial.org/mysql-cast/)

I already use this Laravel Migration
$table->integer('tena_type')->unsigned()->nullable()->change();
But it doesn't work because, the data already in the table. In that case it can't change the datatype.I use this DB statement to change the datatype with data.it's working properly.
DB::statement("alter table SYS_tenants modify tena_type integer not null"):

Related

Currently cubic_meter columns are string. Must convert the type to double precision. (Laravel)

Laravel + Postgres
Need to change the type of cubic_meter to double precision
Error im getting when doing the migration
You're using migrations wrong. Try something like:
Schema::table('products', function (Blueprint $table) {
$table->double('cubic_meters')->change();
});

Error with index when converting Laravel mysql migrations to postgresql

I have written about 10 Laravel migrations for a MySQL database. I want to now switch out my database for a Postgresql database but am having some trouble with indexes it seems.
I followed a tutorial about a voting module so I didnt write the migrations myself but they did all work when migrating on MySQL.
The error im getting is as follows;
SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "poll_id" already exists (SQL: create index "poll_id" on "gp_poll_votes" ("poll_id"))
There is no duplicate table and these migrations have been working for the last year or so.
The migration it is getting stuck on is as follows;
Schema::create('gp_poll_votes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('poll_id')->unsigned();
$table->bigInteger('poll_option_id')->unsigned();
$table->bigInteger('vote_count');
$table->timestamps();
$table->index('poll_id', 'poll_id');
$table->index('poll_option_id', 'poll_option_id');
$table->foreign('poll_id')->references('id')->on('gp_polls')->onDelete('cascade');
$table->foreign('poll_option_id')->references('id')->on('gp_poll_options')->onDelete('cascade');
});
There is 2 more migrations associated with the votes which are run before the erroring one, which are;
Schema::create('gp_polls', function (Blueprint $table) {
$table->bigIncrements('id');
$table->tinyInteger('status')->nullable(false)->default(1);
$table->timestamps();
});
and
Schema::create('gp_poll_options', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('poll_id')->unsigned();
$table->bigInteger('image_id')->unsigned();
$table->tinyInteger('status')->nullable(false)->default(1);
$table->timestamps();
$table->index('poll_id', 'poll_id');
$table->index('image_id', 'image_id');
$table->foreign('image_id')->references('id')->on('gp_submit_images');
$table->foreign('poll_id')->references('id')->on('gp_polls')->onDelete('cascade');
});
In Postgres the index names have to be unique across the database it would seem, in MySQL that doesn't seem to matter.
You can create your indexes without passing a second argument, the name of the index, and Blueprint will create a more unique index name for you.
$table->index('poll_id'); // "gp_poll_options_poll_id_index"
It will use something like "{$prefix}{$table}_{$column}_{$typeOfIndex}" to generate the index name for you.

Migration - Cannot Change Double Data Type Value

I have an existing table created with this migration code:
Schema::create('mytable', function (Blueprint $table) {
$table->increments('id');
$table->double('mycolumn',8,2)->unsigned()->default(0);
$table->timestamps();
});
Then I have created another migration file to adjust the value range of my mycolumn field with the migration file below.
Schema::table('mytable', function (Blueprint $table) {
$table->double('mycolumn',15,2)->unsigned()->default(0)->change();
});
However I am getting an error:
In DBALException.php line 283:
Unknown column type "double" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a li
st of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database introspection then you might have forgott
en to register all database types for a Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getM
appedDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot some mapping information.
What am I missing?
the double cannot be changed the way you do for other types, you can fix it using Doctrine\DBAL\Type
You can fix it in this way:
use Doctrine\DBAL\Types\FloatType;
use Doctrine\DBAL\Types\Type;
public function up() {
if (!Type::hasType('double')) {
Type::addType('double', FloatType::class);
}
Schema::table('mytable', function($table) {
$table->double('mycolumn',15,2)->default(0)->change();
.....
});
}
You are missing this from the documentation
Only the following column types can be "changed": bigInteger, binary, boolean, date, dateTime, dateTimeTz, decimal, integer, json, longText, mediumText, smallInteger, string, text, time, unsignedBigInteger, unsignedInteger and unsignedSmallInteger.
So double cannot be changed.
I haven't tried but you can maybe use a RAW MySQL query like this, try it locally first of course:
DB::statement('alter table mytable modify mycolumn DOUBLE(15,2) DEFAULT 0');
I'm not sure if this will help, but you may use decimal or float instead of double in this case, though float will not work if you want a limited amount of decimal places.
So it will look like:
$table->decimal('mycolumn',15,2)->unsigned()->default(0)->change();

Populate table after running a migration

Background:
In my application, Users can own Files. It used to be that a File belongs to a single User, so I used a one-to-many relationship. Now, the requirements have changed, and my relationship needs to become many-to-many.
Previously, the data structure looked like this:
files
(
id,
user_id
...
);
and the new data structure looks like this:
files
(
id,
...
);
file_user
(
id,
file_id,
user_id,
);
Problem:
I created a migration to change my data structure, like this:
public function up()
{
Schema::create('file_user', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('file_id', 36);
$table->string('user_id', 36);
});
}
Then, I set up the relationship in the corresponding models. Now i need to convert the old data into the new data structure. That means taking all the existing Files, and creating a new record in the file_user table. The code itself is simple:
foreach(File:all() as $file) {
$file->users()->attach($file->user_id);
}
I want to run this code alongside the migration, so that after running the migration, the table will populate. However, when I try to put it directly in the migration file like this:
public function up()
{
// create table
Schema::create('file_user', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('file_id', 36);
$table->string('user_id', 36);
});
// convert old data
foreach(File:all() as $file) {
$file->users()->attach($file);
}
}
I get an exception:
PDOException: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "file_user" does not exist. It seems like the table has not been created yet at the time when the code is trying to run.
Question:
Is there a way that I can put the conversion code inside the migration file to make it work like expected? Or is there a better way to achieve this?
Try to create a second migration file, insert the // convert old data foreach(File::all() as $file) ... part there and migrate the two files together.

Updating columns with migration Laravel 5.4

I have a running application, I see a field in a form is not required and can be left empty. but by the migrations, that field in database is set to be "not null". I wanted to to change it so I did it by checking Null. But how I do the same thing with migrations?? I read documentation and created this
public function up()
{
Scheme::table('modules', function (Blueprint $table) {
$table->text('content')->nullable();
});
}
but when I run migration, it give me error table already exists (obviously, because other migration files are there). How should I do it to achieve my target.
Change your code to this and notice the ->change() part:
public function up()
{
Scheme::table('modules', function (Blueprint $table) {
$table->text('content')->nullable()->change();
});
}
Documentation on changing columns
NB:
You'll need the Doctrine/DBal package in order for this to work:
Before modifying a column, be sure to add the doctrine/dbal dependency to your composer.json file. The Doctrine DBAL library is used to determine the current state of the column and create the SQL queries needed to make the specified adjustments to the column

Resources