Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[DB error] PostgreSQL, for tables without sequences get "Undefined table: ERROR: relation '%_seq' does not exist"

未关闭
#54 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
45/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
php, postgresql
领域
database

调研方向

从 Codeception\Lib\Driver\PostgreSql::lastInsertId 开始,然后追踪 Db::haveInDatabase 如何将其用于 PostgreSQL 驱动程序。使用一个具有整数主键但没有 sequence 的表复现该示例,并添加覆盖测试,以表明在不存在 sequence 时插入也能在不出现 undefined-relation 错误的情况下完成。

由索引模型根据 Issue 内容生成。

描述

Hi, found this little issue, I get an error when insert a row into a table that has NO sequence, one possible use case - it could happen with UUID as primary key that are generated on an application side, so it's not completely imaginary case :)

I'm using postgres:15, codeception/module-db looks like version 3.1.0,
and for example I have a table (for simplicity, integer primary key, no sequence)

create table t
(
    c integer not null primary key
);

Then I call \Codeception\Module\Db::haveInDatabase ($this->tester->haveInDatabase('t', ['c' => 1]);) in my test and see in the console

[DB error] SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "t_c_seq" does not exist
image

Row is inserted, but after it is trying to extract last inserted ID and (cause it's not possible) it fails.

Happens here in \Codeception\Lib\Driver\PostgreSql::lastInsertId

    public function lastInsertId(string $tableName): string
    {
        $sequenceName = $this->getQuotedName($tableName . '_id_seq');
        $lastSequence = null;

        try {
            $lastSequence = $this->getDbh()->lastInsertId($sequenceName);
        } catch (PDOException $exception) {
            // in this case, the sequence name might be combined with the primary key name
        }
        if (!$lastSequence) {
            $primaryKeys = $this->getPrimaryKey($tableName);
            $pkName = array_shift($primaryKeys);
// next line we get an error
            $lastSequence = $this->getDbh()->lastInsertId($this->getQuotedName($tableName . '_' . $pkName . '_seq'));
	}

        return $lastSequence;
    }

And I guess technically that is not an error, because we never should be checking for a last inserted ID in those cases.

Not really sure how to better handle this case, maybe it is possible to add some additional checks before calling \Codeception\Lib\Driver\Db::lastInsertId, trying to detect if a sequence for the given table even exists. If there are no sequence - no need to call \Codeception\Lib\Driver\Db::lastInsertIdmaybe?

In that case I found this monster here https://dba.stackexchange.com/questions/260975/postgresql-how-can-i-list-the-tables-to-which-a-sequence-belongs

SELECT t.oid::regclass AS table_name,
       a.attname AS column_name,
       s.relname AS sequence_name
FROM pg_class AS t
         JOIN pg_attribute AS a
              ON a.attrelid = t.oid
         JOIN pg_depend AS d
              ON d.refobjid = t.oid
                  AND d.refobjsubid = a.attnum
         JOIN pg_class AS s
              ON s.oid = d.objid
WHERE d.classid = 'pg_catalog.pg_class'::regclass
  AND d.refclassid = 'pg_catalog.pg_class'::regclass
  AND d.deptype IN ('i', 'a')
  AND t.relkind IN ('r', 'P')
  AND s.relkind = 'S';

Maybe it is possible to filter by table and if there is no sequences - return 0 or smth like that. But I'm not sure how to handle different postgresql's version issues - if there's any...

Or add a custom exception and throw it in the lastInsertId method, checking sequence's existence before calling \PDO::lastInsertId. Don't like that one though) But the names for a sequence are building and checking inside this method..

Would be happy to discuss or just hear your thoughts about it, and if I'm lucky even make MR :)
I could try to provide a test that covers that case and fails?

主要语言
PHP
星标
23
派生
31
PR 合并指标
30 天内没有已合并 PR

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

Codeception/module-db 的其他 Issue

查看 Codeception/module-db 的全部 Issue

相似的 Issue

更多 PHP Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。