【问题标题】:Seeding NULL values into NOT NULL columns with CI4使用 CI4 将 NULL 值播种到 NOT NULL 列中
【发布时间】:2022-12-23 21:54:23
【问题描述】:

我在使用 CodeIgniter 4 播种器时遇到问题,到目前为止我找不到任何解决方案。我使用 CodeIgniter 4 迁移来生成我的表,默认情况下列是 NOT NULL。在 MySQL 中播种数据库没有问题,即使我只插入了一些列,这会产生其他任何东西NULL.

问题是,如果我更改为 PostgreSQL,迁移运行正常。我只需要将DOUBLE 更改为NUMERIC。播种机并不那么容易。我得到的第一个错误是Message: pg_query(): Query failed: ERROR: null value in column "created_at" violates not-null constraint ,这很奇怪,因为在使用 MySQL 时,这些列是正常填充的。但是,即使我手动告诉我的迁移填充 create_atupdated_at,我仍然在 NOT NULL 的任何其他列中收到此错误,而在 MySQL 中,它们只是留空。

我认为在这种情况下我对 CI4、MySQL 或 PostgreSQL 有一些误解,如果有人能解释一下,我会很高兴。

因此,总而言之,我尝试使用 PostgreSQL 为数据库播种,这在 MySQL 中运行良好,并且它不会让我不在播种机中未指定的许多其他字段中插入任​​何值。而且我担心这会成为表单和这类事情的问题,因为某些字段未填写会导致相同的错误。

为了澄清,这是我数据库中表的迁移:

class Configuracoes extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'id_config'       => [
                'type'           => 'INT',
                'constraint'     => 9,
                'usigned'        => true,
                'auto_increment' => true,
            ],

            'nome_do_app' => [
                'type'       => 'VARCHAR',
                'constraint' => 128
            ],

            'tema' => [
                'type' => 'INT'
            ],

            'xNome' => [
                'type'       => 'VARCHAR',
                'constraint' => 128
            ],

            'xFant' => [
                'type'       => 'VARCHAR',
                'constraint' => 128
            ],

            'CNPJ' => [
                'type'       => 'VARCHAR',
                'constraint' => 14
            ],

            'telefone' => [
                'type'       => 'VARCHAR',
                'constraint' => 11
            ],

            'endereco' => [
                'type'       => 'VARCHAR',
                'constraint' => 256
            ],

            'arquivo-imagem-de-fundo-login' => [
                'type'       => 'VARCHAR',
                'constraint' => 128
            ],

            'logomarca' => [
                'type'       => 'VARCHAR',
                'constraint' => 128
            ],

            'created_at' => [
                'type'   => 'DATETIME'
            ],

            'updated_at' => [
                'type'   => 'DATETIME'
            ],

            'deleted_at' => [
                'type'   => 'DATETIME'
            ]
        ]);

        $this->forge->addKey('id_config', true);
        $this->forge->createTable('configuracoes');
    }

这张桌子的播种机:

        $this->db->table('configuracoes')->insert([
            'nome_do_app' => 'App',
            'tema'        => '4',
            'xNome'       => 'name',
            'xFant'       => 'name',
            'CNPJ'        => '0000000000000',
            'telefone'    => '(000) 0000-0000',
            'endereco'    => 'adress'
        ]);

你可以看到播种机只填充了一些列,所以运行它我会得到和以前一样的错误,要求每一列丢失。我可以用空格填充缺失的列,它会运行得很好,但我需要了解它为什么会发生,以及它是否会干扰我的代码中的 POST 方法和排序。

【问题讨论】:

  • MySQL 没有这个错误,它会将显式 NULL 值(由 INSERT 语句的 VALUES 子句提供)转换为其他内容吗?
  • 能否请您提供 MySQL 和 PostgreSQL 表的 DDL 以及用于 INSERT 的 SQL 语句?

标签: mysql postgresql codeigniter


【解决方案1】:

我学到了一两件事来试图解决这个问题,所以不妨与任何感兴趣的人分享。如果我说错了,请随时纠正我,我很乐意编辑我的答案。

MySQL 和 PostgreSQL 在处理 NOT NULL 约束方面有一些差异,我的代码没有考虑这些差异。

在尝试使用以下代码为 MySQL 数据库播种时:

$this->db->table('configuracoes')->insert([
            'nome_do_app' => 'App',
            'tema'        => '4',
            'xNome'       => 'name',
            'xFant'       => 'name',
            'CNPJ'        => '0000000000000',
            'telefone'    => '(000) 0000-0000',
            'endereco'    => 'adress'
        ]);

seeder 之外的任何其他内容都将被赋予一个 NULL 值,MySQL 不会抱怨它,即使这些字段被定义为 NOT NULL。虽然我不确定它是如何深入工作的,但这是我在尝试解决此问题时所看到的。

与 MySQL 相比,PostgreSQL 的另一个不同之处在于 date 字段类型。在 MySQL 数据库中保留此字段 NULL 时,它会自动将其设置为 0000-00-00 00:00:00:000。但是 PostgreSQL 不会接受这样的值,NULL 当然也不会。除非你告诉 Postgre 在该字段中接受一个 NULL 值,否则那将像其他字段一样只是一个空字段。我的代码也没有考虑这个变化。

使用 PostgreSQL,如果一个字段设置为 NOT NULL,您不能简单地告诉 Postgre 插入一个 NULL 值,甚至不能手动这样做。我的整个数据库都设置为NOT NULL,因为它永远不会成为 MySQL 的问题。

解决方案:我检查了所有迁移,无论如何只在实际需要值的字段中留下NOT NULL。然后在为表做种时,我考虑了 NOT NULL 字段并手动插入了一个默认值,例如空格或零。

谢谢所有试图提供帮助的人!

PSA:我不是从一开始就创建这个数据库的人,我只是在维护和继续别人做的一个项目。因此,对于以这种方式构建它的选择,我真的不能说什么。

【讨论】:

    猜你喜欢
    • 2010-10-15
    • 2014-11-19
    • 2019-08-23
    • 2011-03-12
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 2021-09-15
    相关资源
    最近更新 更多