-
-
Notifications
You must be signed in to change notification settings - Fork 192
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
Mysql store Boolean as TinyInt(1) #440
Comments
I'm not sure what is the problem here. |
No any way, how recognize column as boolean, except add to column name something like bool. For example: is_expired_bool |
@uldisn you are talking about different problem than @WinterSilence right? |
So the value is not cast to boolean? |
@bizley enum's too work strange: in form - select, in model - string without rules as |
@bizley cast where? in yii code or in db? |
What is the type of such attribute when you fetch the model from a database? |
@bizley https://dev.mysql.com/doc/refman/5.7/en/numeric-type-syntax.html it's stored as tinyint but in sql you can set as true/false |
I'm not asking how it's stored, MySQL stores booleans as tinyInts. I'm asking what are you getting in the model when you fetch it from DB. |
For me actually is problem with booleans:
|
@uldisn this problem has been mentioned several times already in different issues. Main problem here is to properly handle enums in all database engines that Yii supports. So far we don't have one elegant solution. Please don't hijack this issue. |
@bizley after my fix: /**
* @property bool|null $is_bool
*/
class TblTest1 extends \yii\db\ActiveRecord
{
/**
* {@inheritDoc}
*/
public function rules(): array
{
return [
...
[['is_bool'], 'boolean'],
...
] |
@bizley i talk about boolean, not enum. gii use fix for postgresql without any problem |
Oh, I think I understand now. Generating model from MySQL DB is not preparing |
In recent MySQL versions these two types aren't equivalent:
But overall, we can add an alias, I see no problem with it. @WinterSilence are we correct that you expect a field with |
@samdark To cover more cases, value may be any value converting to boolean/int(to BC) before validation. Boolean values are stored as integers 0 (false) and 1 (true). I check it's valid for most popular db: mysql, postgres, mssql, sqllite.
|
We can do it for Gii for sure. As for doing it at schema level, it may break things. |
@samdark I'm extended class protected function generateProperties($table)
{
$properties = [];
$driverName = $this->getDbDriverName();
foreach ($table->columns as $column) {
switch ($column->type) {
case Schema::TYPE_SMALLINT:
case Schema::TYPE_INTEGER:
case Schema::TYPE_BIGINT:
$type = 'int';
break;
case Schema::TYPE_TINYINT:
if ($driverName !== 'pgsql' && $column->size === 1 && in_array($column->defaultValue, [0, 1])) {
$type = 'bool';
} else {
$type = 'int';
}
break; can be possible set 2 types for column? public function generateRules($table)
{
$types = [];
$lengths = [];
$driverName = $this->getDbDriverName();
foreach ($table->columns as $column) {
if ($column->autoIncrement) {
continue;
}
if (!$column->allowNull && $column->defaultValue === null) {
$types['required'][] = $column->name;
}
switch ($column->type) {
case Schema::TYPE_SMALLINT:
case Schema::TYPE_INTEGER:
case Schema::TYPE_BIGINT:
$types['integer'][] = $column->name;
break;
case Schema::TYPE_TINYINT:
if ($driverName !== 'pgsql' && $column->size === 1 && in_array($column->defaultValue, [0, 1])) {
// maybe add extra rule [$column->name, 'in', 'range' => [0, 1, true, false, null], 'strict' => true]
$types['boolean'][] = $column->name;
} else {
$types['integer'][] = $column->name;
} off top: display column from related model as select in form. it can be possible? |
2 types at the same time? Ummm... no? But you've got overall idea alright. |
@samdark how you validate multi type values? /**
* Checks type of field value.
*
* @param mixed $value Field value.
* @param string ...$types Valid value types.
* @return bool
*/
public static function type($value, string ...$types): bool
{
$type = gettype($value);
if (in_array($type, $types, true)) {
return true;
}
// Check extra types as "numeric", "iterable", "countable" and etc.
foreach ($types as $type) {
$func = 'is_' . $type;
if (function_exists($func) && $func($value)) {
return true;
}
}
return false;
} yii have validation rules like that? |
Not really. |
what do you mean? |
I mean there are no such built-in validators. |
We have modified gii to do this instead about a years ago, and we've never looked back. It works as expected this way. This is the same as @WinterSilence has shown.
It even has a benefit that you'll still be able to use |
@michaelarnauts |
How are you going to know from the schema that a tinyint(1) column should be "just" a bolean? Example: a tinyint(1) col for different states that can be 1,2,3,4,... is totally valid, but clearly not a boolean. (My) conclusion: The reason why one want a boolean validator for this in many cases is quite clear to me, but I don't think it's a good idea to "guess" that it's a boolean based on a DB type that can also be "something else". |
Something else:
|
In gii generator model screen add input field, where write comma separated boolean field names |
What steps will reproduce the problem?
Create table in mysql8.* with boolean column.
What's expected?
Generator work with column
tinyint(1)
as is.What do you get instead?
Additional info
The text was updated successfully, but these errors were encountered: