-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Schema Builder: Error when changing a column to a tinyInteger #8840
Comments
As a workaround you may be able to use boolean, which at least in MySQL seems to be functionally identical to tinyint. see: http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html
|
Have the same issue here (w. lumen). Thanks for the fix! tinyint is still makes sense in a few cases though... |
I have the same problem with tinyInteger |
+1. I ran into this today while writing a migration to convert a boolean column into a tinyint. @GrahamCampbell, why was this issue closed? |
@GrahamCampbell I'd like to know why this issue was closed as well. Simply using |
+1 |
+1 Tried to convert My solution was to convert it to
|
I'm having the same issue with mediumInteger(). |
+1 |
+1 having the same issue. Why has the issues being closed? |
@GrahamCampbell this is a reproducible bug. I hit it with mediumInteger(). Can you clarify why this issue was closed? Are you seeing something we are not? Edit: The workaround did not work for me. I did not get an error, but after the migrations run the database does not show a mediumInt. |
@taylorotwell We have a legitimate bug here; but I believe the worst problem is the fact that it was closed by @GrahamCampbell without any comment whatsoever. |
Similar problem here. I tried to change an existing tinyInteger to unsigned(). So the boolean workaround is not applicable in my case. |
Running into same issue when we are trying to change tiny int column to not allow nulls using this statement $table->tinyInteger('bedrooms')->nullable(false)->change(); |
+1 |
+1 Laravel 5.2.19
Doesn't work, throws error:
|
Solution: |
@sergey-rud While that does work, it's not really a solution to the problem at hand. It's just a workaround. |
@GrahamCampbell Please comment on why this was closed? At least give us an idea here so people can figure out how to fix the problem otherwise. Closing an issue with this many active people still commenting on it, without at least an explanation, isn't helpful at all. |
It is not a laravel bug. Please take it up with doctrine. |
See that's helpful. This could've been done three months ago. |
You didn't need me to tell you that. |
Was just coming here to let the thread know that I've opened an issue in DBAL - but it turns out GitHub is wicked smaht. |
Going to re-open this here to prevent duplicate issues coming up (if possible). |
Take a look at this comprehensive list of types available in Tinyint is only mentioned there as an implementation of the boolean type in the mapping matrix. Quickly skimming through the source code doesn't show It's hard to read through their issues because they are being imported via/from JIRA, but this looks closest to describing the issue at hand but has been closed by a bot for whatever reason: doctrine/dbal#2011 - notably the last comment
So summarized: I do think that currently this is a flaw in the Laravel Schema component as it erroneously assumes that 2c |
No, Only a quick thought. BTW: The JPA (Java Persistence API) is very similar to Doctrine and it behaves like that. |
While I agree that this is a Doctrine issue/inconsistency; they just confirmed that they won't be fixing it. Could this please be reconsidered to be added to Laravel to avoid a mess in migrations just to set an initial (non-default) value to new, non-nullable columns. (docs & implementation example) |
A pr was merged that would allow you to register a custom DBAL type if you want. This is probably the best alternative we can offer. So gonna close this. |
Just want to clarify that #28214 actually already implements tinyInteger as a custom class... for MySQL (notably SQLite & SQL Server are still missing at this point) |
@jlsjonas thanks for clarifying! :) |
Wow Google a problem and its my own issue from 4 years ago! The above conversation is all very confusing and at times contradictory, so here's documentation on what to actually do... The Here is an example from a test https://github.com/laravel/framework/blob/841a28067b03979603e41dd80729cb8581a91e95/tests/Integration/Database/Fixtures/TinyInteger.php I placed it in App\Doctrine\TinyInteger.php but you can place it anywhere.
Then use this is in your migration file.
@JacksonIV what is the thinking behind not making the TinyInteger class available within the Laravel Framework itself? |
Confirmed the above solution works great. I come from JavaScript land, so PHP isn't my strong suit. For others like me:
Besides those points, you should be able to copy/paste the |
@robjbrain @agm1984 following this steps works in case of |
To solve problem with foreign key you need to create UnsignedTinyInteger class
And add it to your migration
|
public function up()
{
$database = \Illuminate\Support\Env::get('DB_DATABASE');
DB::statement("ALTER TABLE `$database`.`game_prizes` ADD COLUMN `status` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '状态' AFTER `remark`;");
}
public function down()
{
Schema::table('game_prizes', function (Blueprint $table) {
$table->dropColumn('status');
});
} Perfect. It hasn't been fixed for years.This is the best way. |
Hey guys, I'm having the exact same problem, when trying to convert a field from |
After so much, still, it didn't work. So, I used raw query.
|
So after 7 years this still hasn't been fixed? I've just run into the issue. When I add both |
As others, I think it is Laravel issue. DBAL does not want to support TINYINT. Laravel uses DBAL but still tries to support TINYINT but this support is incomplete, this issue is the result of inconsistency. However, I have to say that this behavior of Laravel is documented, so technically not a bug |
Secondly, Laravel provides means to solve this problem, below is complete solution for MySQL for both
<?php
namespace App\Doctrine;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
class TinyInteger extends Type
{
/**
* The name of the custom type.
*/
public const NAME = 'tinyinteger';
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $value === null ? null : (int)$value;
}
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
$unsigned = !empty($column['unsigned']) ? ' UNSIGNED' : '';
$autoincrement = !empty($column['autoincrement']) ? ' AUTO_INCREMENT' : '';
return 'TINYINT' . $unsigned . $autoincrement;
}
/**
* {@inheritdoc}
*/
public function getName(): string
{
return static::NAME;
}
/**
* {@inheritdoc}
*/
public function getBindingType(): int
{
return ParameterType::INTEGER;
}
}
<?php
use App\Doctrine\TinyInteger;
return [
// ...
'dbal' => [
'types' => [
TinyInteger::NAME => TinyInteger::class,
],
],
// ...
]; That is enough, now your Laravel project knows TINYINT, no special code needed in migrations in contradistinction to other solutions above. Inspired by Hope it helps to someone. |
I think the fix suggested by @dmitry-kulikov should be added to the framework, if it can be done for all supported databases by Laravel. |
@dmitry-kulikov This might be the first example where one can use both tinyint and tinyint unsigned at the same time. I have not tested it yet, but this might be the missing piece of information. |
Here is a simple example of how to add <?php
namespace App\Foundation\Database\DBAL;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
class EnumType extends Type
{
/**
* {@inheritdoc}
*/
public function getName(): string
{
return 'enum';
}
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
$values = array_map(fn ($string) => $platform->quoteStringLiteral($string), $column['allowed']);
return 'ENUM(' . join(', ', $values) . ')';
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $value;
}
} Simply register this class in 'dbal' => [
'types' => [
'enum' => EnumType::class,
],
] Also, if Laravel gods will accept, I have submitted a PR (#47037) so we could easily extend / modify any existing DBAL type by registering in |
This is already fixed on Laravel 10.x #45487 If you are not utilizing SQLite, You may remove |
Oh wow, so we can change any of types now? This is gold but why this is not documented. I would not know if you did not tell me. :-) |
@linaspasv Yes you can modify any type, please check PR #45487 for more detail. It's already documented. You would need |
Hm, then maybe Laravel installs update - yeh, indeed, you need to have |
When modifying a column to be a tinyint like so (previously a VARCHAR(10) )
The following error is given:
"getTypesMap()" returns the following:
Creating a tinyInteger column works fine, it's only when modifying a column that the error occurs
The text was updated successfully, but these errors were encountered: