[DB error] PostgreSQL, for tables without sequences get "Undefined table: ERROR: relation '%_seq' does not exist"
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 45/100
Rechercherichtung
Beginnen Sie bei Codeception\Lib\Driver\PostgreSql::lastInsertId und verfolgen Sie anschließend, wie Db::haveInDatabase es für den PostgreSQL-Treiber verwendet. Reproduzieren Sie das Beispiel mit einer Tabelle, die einen Integer-Primärschlüssel, aber keine Sequenz hat, und ergänzen Sie Tests, die zeigen, dass die Einfügung ohne den Fehler undefined-relation abgeschlossen wird, wenn keine Sequenz vorhanden ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
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
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?
- Vorherrschende Sprache
- PHP
- Sterne
- 23
- Forks
- 31
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus Codeception/module-db
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 42/100
Codeception/module-db#87 ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 25/100
Codeception/module-db#85 ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 35/100
Codeception/module-db#68 · 1 Kommentar ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 35/100
Codeception/module-db#67 ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 38/100
Codeception/module-db#58 ·
Alle Issues in Codeception/module-db
Ähnliche Issues
-
tooling
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
-
UX
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
ProfessionalWiki/NeoWiki#1525 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 90/100
OpenConext/OpenConext-engineblock#2122 ·
-
Bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
Automattic/safe-publish#594 ·