【问题标题】:cant store 0 or 1 as boolean laravel postgresql不能将 0 或 1 存储为布尔 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 项目中

标签: laravel postgresql


【解决方案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 查询。 stackoverflow.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;
    

    【讨论】:

      猜你喜欢
      • 2013-09-03
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 2021-11-29
      • 2022-07-28
      • 2021-09-11
      相关资源
      最近更新 更多