How to change datatype float to string in laravel migration - laravel

I am trying to change datatype of one of my field from float to string but i am facing an issue
SQLSTATE[42000]: Syntax error or access violation: 1064 You have
an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near '' at line 1 (SQL: ALTER TABLE patient
MODIFY height varchar)
my migration:
public function up()
{
DB::statement('ALTER TABLE patient MODIFY height varchar');
}
How i can achieve my target:
Your help need here
public function up()
{
Schema::table('patient', function (Blueprint $table) {
$table->string('height')->change();
});
}

You can use laravel's change method :
public function up()
{
Schema::table('patient', function ($table) {
$table->string('height')->change();
});
}
Also your SQL syntax should be :
ALTER TABLE patient MODIFY height varchar(255);
Update :
As per the laravel's 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 Laravel's change will not work directly as you have a float column which laravel internally makes as double(8,2). Please update your raw SQL syntax using what I have given and try again.

Related

Update laravel migration to nullable without changing datatype

In Laravel 6, I have a table companies and I want to change the column card to nullable.
I created a new migration and I can change it using
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('companies', function (Blueprint $table) {
$table->double('card')->nullable()->change();
});
}
But the problem is doctrine/dbal only supports some specific datatypes to update.
Error: 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 list of all the
known types with \Doctrine\DBAL\Types\Type::getTypesMap().
Is there any way I can update this column to nullable without touching its datatype? or any DB statement?
I can use
DB::statement('ALTER TABLE `companies` CHANGE `card` `card` INT NULL DEFAULT NULL;');
but I am concern is this right way to do?
according to Laravel doc:
The following column types can be modified: bigInteger, binary,
boolean, date, dateTime, dateTimeTz, decimal, integer, json,
longText, mediumText, smallInteger, string, text, time,
unsignedBigInteger, unsignedInteger, unsignedSmallInteger, and uuid.
so if your column is not from those types it will not be able to change

Change the datatype in the column with data in laravel migration

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"):

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();

Laravel Database Migration Column altered to Unique and Nullable causing error

I am attempting to integrate social logins with my existing laravel app. I am attempting to change email and password to nullable but I also need email to remain unique. On executing my migration I am getting an error for duplicate key name 'users_email_unique'
Laravel 5, already fixed the issue with enum I had for altering a column.
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique()->nullable()->change();
$table->string('password')->nullable()->change();
});
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique' (SQL: alter table users add unique users_email_unique(email))
Exception trace:
1 Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:119
2 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117
Edit
If I remove Unique() from email, will it remain unique since that was previously set in a different migration?
You can change the uniqueness behaviour in a new migration by following below:
public function up()
{
Schema::table('contacts', function (Blueprint $table) {
$table->dropUnique(['email']);
});
}
/**
* Reverse the migrations.
*
*/
public function down()
{
Schema::table('contacts', function (Blueprint $table) {
$table->string('email')->unique()->change();
});
}
The Nullable() attribute will stay with the email column, since it was created with it.
It sound like the database is detecting a repeated value. That's impossible with nulls, so it could be an empty string maybe.
If that's the case, you can write a mutator function in your model to check if the value is empty and, set it to null before it goes to the database engine, like this:
public function setNameOfYourAttribute($value) {
if ( empty($value) ) {
$this->attributes['nameofyourattribute'] = NULL;
}
}
Hope it helps.
NOTE:
Full Documentation
Figured this out myself, as mentioned in the comment on the above answer.
Simply because the table was already created with unique() if I remove that it will allow the migration and will also persist the unique() functionality that was in the original User table migration.

Laravel 4.2 Migrations - Alter decimal precision and scale without dropping column

I wish to increase decimal precision and scale for a decimal column.
I am aware that I can drop the column, and re-create it, but doing so will mean losing the data in the column.
Is there a way using Laravel Schema::table that I can alter the precision and scale of the column without dropping it?
e.g. something like:
Schema::table('prices', function(Blueprint $t) {
$t->buy_price->decimal(5,2);
});
this worked for me:
public function up()
{
Schema::table('prices', function(Blueprint $t) {
$t->decimal('buy_price', 5, 2)->change();
});
}
when rolling back use original precision values of 3, 1 instead
public function down()
{
Schema::table('prices', function(Blueprint $t) {
$t->decimal('buy_price', 3, 1)->change();
});
}
I avoid DB specific "raw" statements as they might fail when I change to another DBMS engine. So I let Laravel handle necessary syntax when working w/DB
Just create another migration and in the up method add following code:
public function up()
{
// Change db_name and table_name
DB::select(DB::raw('ALTER TABLE `db_name`.`table_name` CHANGE COLUMN `buy_price` `buy_price` decimal(10,2) NOT NULL;'));
}
Also in the down method just set the old value so you can roll-back:
public function down()
{
// Change db_name and table_name
DB::select(DB::raw('ALTER TABLE `db_name`.`table_name` CHANGE COLUMN `buy_price` `buy_price` decimal(5,2) NOT NULL;'));
}
Then migrate as usual from the terminal/command prompt using php artisan migrate.
Didn't work for me, using select gives me a General Error: 2053 because select expects aa array to be returned. I'm not sure if it's the version of MySQL, or a windows/linux thing.
I had to use DB:statement instead:
public function up()
{
// Change db_name and table_name
DB::statement(DB::raw('ALTER TABLE `db_name`.`table_name` CHANGE COLUMN `buy_price` `buy_price` decimal(10,2) NOT NULL;'));
}
and
public function down()
{
// Change db_name and table_name
DB::statement(DB::raw('ALTER TABLE `db_name`.`table_name` CHANGE COLUMN `buy_price` `buy_price` decimal(5,2) NOT NULL;'));
}
Hope this helps anyone who comes across this.

Resources