不能将 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 值也是如此,例如 0null 等。

【讨论】:

我能够在不指定 $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

布尔值,如果不是0或1,运行时错误

将学说实体布尔字段设置为 0 而不是 null

如何使用 linq 将“Y”或“N”值转换为布尔值?