pg-mem
pg-mem copied to clipboard
Typeorm integration fails after 0.2.30
typeorm introduced this change link to diff after which pg-mem fails to integrate. It seems related to this #58 issue.
it('can process updated typeorm columns schema selection', () => {
simpleDb();
const sql = `SELECT columns.*,
pg_catalog.col_description(('"' || table_catalog || '"."' || table_schema || '"."' || table_name || '"')::regclass::oid, ordinal_position) AS description,
('"' || "udt_schema" || '"."' || "udt_name" || '"')::"regtype" AS "regtype",
pg_catalog.format_type("col_attr"."atttypid", "col_attr"."atttypmod") AS "format_type"
FROM "information_schema"."columns"
LEFT JOIN "pg_catalog"."pg_attribute" AS "col_attr"
ON "col_attr"."attname" = "columns"."column_name"
AND "col_attr"."attrelid" = (
SELECT
"cls"."oid" FROM "pg_catalog"."pg_class" AS "cls"
LEFT JOIN "pg_catalog"."pg_namespace" AS "ns"
ON "ns"."oid" = "cls"."relnamespace"
WHERE "cls"."relname" = "columns"."table_name"
AND "ns"."nspname" = "columns"."table_schema"
)`;
expect(many(sql).length)
.to.equal(4);
expect(many(sql))
.to.deep.equal([{ regtype: 'text' }
, { regtype: 'jsonb' }
, { regtype: 'integer' }
, { regtype: 'text' }]);
});
Error: column "columns.table_name" does not exist
Quite good analysis 😊
Actually, this issue is a duplicate of #61 ... and will be fixed when the underlying cause #38 is fixed.
It requires a non trivial refactoring of how references are resolved in pg-mem, which I did not had the time do carry to its end yet :(
This is not an issue with Typeorm 0.2.29 and lower, if downgrading is an option for you, though.
ps: I'm leaving this issue open for future readers
Hi, is there a workaround we can do? Or perhaps I can help with refactoring given enough context/help. Downgrading typeorm is not an option for us unfortunately :(
Hi, I currently dont have any tested workaround, but I never looked into one.
That said, this could work:
const db = newDb();
const incriminatedQuery = `SELECT columns.*,
pg_catalog.col_description(('"' || table_catalog || '"."' || table_schema || '"."' || table_name || '"')::regclass::oid, ordinal_position) AS description,
('"' || "udt_schema" || '"."' || "udt_name" || '"')::"regtype" AS "regtype",
pg_catalog.format_type("col_attr"."atttypid", "col_attr"."atttypmod") AS "format_type"
FROM "information_schema"."columns"
LEFT JOIN "pg_catalog"."pg_attribute" AS "col_attr"
ON "col_attr"."attname" = "columns"."column_name"
AND "col_attr"."attrelid" = (
SELECT
"cls"."oid" FROM "pg_catalog"."pg_class" AS "cls"
LEFT JOIN "pg_catalog"."pg_namespace" AS "ns"
ON "ns"."oid" = "cls"."relnamespace"
WHERE "cls"."relname" = "columns"."table_name"
AND "ns"."nspname" = "columns"."table_schema"
)`;
db.public.interceptQueries(text => {
if (text === incriminatedQuery) {
return [];
}
return null;
})
This will intercept the introspection query, which we know for a fact that it will not return anything on a blank database => forcing it to return []
is thus OK.
I did not test it, and the incriminatedQuery
is probably wrong (at least the whitespace padding introduced here will be wrong).
Could you test that, tweak the query that fails, and tell me if it works (and repost here the right query if that works for others !)
Thanks :)
https://github.com/oguimbal/pg-mem/issues/81#issuecomment-933654078 The code above works for me except this detail:
if (text === incriminatedQuery) {
return [];
In my query a dynamic (based on entities) WHERE
-clause also generates.
So I replaced this place with:
if (text.replace(/[\n ]/g, '').startsWith(incriminatedQuery.replace(/[\n ]/g, ''))) {
return [];
And now it works. Still waiting for this issue to be resolved though.