不能将 0 或 1 存储为布尔 laravel postgresql
Posted
技术标签:
【中文标题】不能将 0 或 1 存储为布尔 laravel postgresql【英文标题】:cant store 0 or 1 as boolean laravel postgresql 【发布时间】:2021-07-24 19:41:57 【问题描述】:我能够将布尔值存储为 0 或 1 ,但突然间它不断向我返回错误
column \"trial\" is of type boolean but expression is of type integer
我正在使用带有 laravel 8 的 postgresql 13
我该如何解决这个问题?
【问题讨论】:
展示你的模型和你的桌子 @AhmedRafie,php-pgsql 已经在我的系统上更新了,这个问题发生在我所有的 Laravel-Postgres 项目中 bugs.php.net/bug.php?id=81002 【参考方案1】:如果您使用的是 PHP 7.4.18 或 8.0.5,请注意重大变化:
来自Github PHP #6801:
总而言之,以前如果您在 Postgres 上有一个布尔列 表,您可以在 where 中绑定一个整数值(通常为 0 或 1) 使用 PDO::PARAM_INT 对该列的条件,一切都是 美好的。但是,您现在会收到错误消息。
虽然修复已经恢复,但我们需要降级到 7.4.16 / 8.0.3 或等待下一个补丁发布。见PHP Issue #80892
【讨论】:
这太疯狂了。我在 Docker 构建过程中默默地遇到了这个错误,并且在阅读 CI 失败时非常困惑为什么会发生这种情况。我以为我在我的 Docker 映像中指定php:8.0-alpine
已经足够保守了,但显然不是。令人失望的是,在发布之前没有发现这一点。【参考方案2】:
因为我不确定你的模型,因为你没有分享它......如果你READ THE DOCUMENTATION你会发现你可以cast
一个值。
所以,你的模型应该有这样的属性$casts
:
protected $casts = [
'trial' => 'boolean'
];
这将允许您输入任何值,它总是将其转换回布尔值,因此您可以执行$model->trial = 1
、$model->trial = '1'
或$model->trial = 2
或任何true
-ish 值,它会将其转换为true
,所以你应该没有更多的问题......
false
-ish 值也是如此,例如 0
或 null
等。
【讨论】:
我能够在不指定 $casts 的情况下插入 0 和 1 很长时间,我不知道有什么新的情况可以防止这种情况发生? 你更新了什么?如果我们不知道您为此做了什么,我们将一无所知……您是否将数据库(如 mysql)更改为 PostgreSQL?你更新 Laravel 到 8 了吗?您是否进行了新的迁移?在这开始发生之前你在做什么? 我可以怀疑我对 laravel 从 5.8 到 8 所做的升级,但从那以后它至少工作了 4 天。 你在和别人一起工作吗?我的意思是,使用像 Git 这样的 VCS,所以他/她可以更改代码?你能分享任何这样的数据吗?这不是魔法,你更新并工作了 X 时间然后没有,中间发生了一些事情。也许 PostgreSQL 更新了? 我在使用 docker image version 13 for postgresql ,重启 docker-compose 后可以更新吗?【参考方案3】:我用这个。它对我有用。
'pgsql'
=> ['driver'
=> 'pgsql'
,'url'
=> 环境('DATABASE_URL'
),'host'
=> 环境('DB_HOST'
, '127.0.0.1'
),'port'
=> 环境('DB_PORT'
, '5432'
),'database'
=> 环境('DB_DATABASE'
, 'forge'
),'username'
=> 环境('DB_USERNAME'
, 'forge'
),'password'
=> 环境('DB_PASSWORD'
, ''
),'charset'
=> 'utf8'
,'prefix'
=> 'tbt_'
,'prefix_indexes'
=> 是的,'schema'
=> 'public'
,'sslmode'
=> 'prefer'
,'options'
=> extension_loaded('pdo_pgsql'
) ? array_filter([
PDO::ATTR_EMULATE_PREPARES => 假,
]) : [],
],
【讨论】:
【参考方案4】:据我所知,您可以将 int 存储在 postgres 的 bool 列中,我在几个项目中都尝试过。也许您需要使用以下方法更改您的 trial
列:
ALTER TABLE mytable ALTER COLUMN trial DROP DEFAULT;
ALTER TABLE mytable ALTER trial TYPE bool USING CASE WHEN trial=0 THEN FALSE ELSE TRUE END;
ALTER TABLE mytable ALTER COLUMN trial SET DEFAULT FALSE;
或
ALTER TABLE mytable ALTER COLUMN trial DROP DEFAULT;
ALTER TABLE mytable ALTER trial TYPE bool USING trial::boolean;
ALTER TABLE mytable ALTER COLUMN trial SET DEFAULT FALSE;
source
另一种方法是使用 php 将整数转换为布尔值:
$t = 1;
$f = 0;
$b = !!t; //true
$a = !!f; //false
【讨论】:
由于这是 laravel 相关的问题,可能 op 不使用直接 sql 来创建表,而是使用迁移。 我们可以在迁移中使用 RAW SQL 查询。 ***.com/questions/28787293/run-raw-sql-in-migration 当然可以,但我们也可以使用它。这就是模式构建器的优势 架构生成器不支持using case
【参考方案5】:
已解决
经过大量搜索,我找到了一个更新 pg_cast 以允许 0 和 1 作为布尔值的查询
update pg_cast set castcontext='a' where casttarget = 'boolean'::regtype;
【讨论】:
以上是关于不能将 0 或 1 存储为布尔 laravel postgresql的主要内容,如果未能解决你的问题,请参考以下文章
Telegraf/InfluxDB - 将整数拆分为位或布尔值
PHP Laravel - Eloquent 在调用方法 json 时随机返回布尔字段,有时为 0 1,其他为 true false
如何使用 next.jdbc 将 SQLite 中的 bool 列读入 bool Clojure 值? SQLite 将布尔值存储为 0/1