Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeORM View Entity synchronization (creation) order problems

Using TypeORM, I'm trying to create ViewEntities that depend on each other, for example "View B" select from "View A". No matter what I do I can't get the ViewEntities to get created in the order of dependency. Sometimes "View B" is created first, and the synchronization process fails, because it can't find "View A", since it's not created yet.

The error:

QueryFailedError: relation "public.course_item_view" does not exist

Solutions I have tried:

  • Renaming the ViewEntity files (to check if the system uses ABC ordering on file names)
  • Renaming the ViewEntity classes (to check if the system uses ABC ordering on class names)
  • Renaming the ViewEntity's "name" property (to check if the system uses ABC ordering on the final SQL view names)
  • Reordering the ViewEntity class references in the "entities: []" array of the connection options
  • Reordering the ViewEntity class imports in the file where I declare the connection options
  • Removing/Adding the file again (to check if the system uses Creation Date based ordering)
  • Modifying the files (to check if the system uses Modification Date based ordering)

All of these failed. I cannot figure out how the system determines the order in which the view's are created. Any help would be GREATLY appreciated!!

Expected Behavior

The view's should be created in an order that is either specified by a property inside the views, or the order should be resolved automatically from the SELECT statements (dependency array), or it should be based on the order in which I reference the ViewEntities in the "entities: []" array of the connection options, or any other solution would be perfect where one could determine the order in which the ViewEntities are created.

Actual Behavior

The ViewEntites are created in an order that I honestly can't understand. Sometimes a dependent ViewEntity is created before the ViewEntitiy it depends on. This causes the synchronization to fail.

File name: "CourseItemView" which resolves to: "course_item_view"

@ViewEntity({
    expression: `
SELECT
    "uvcv"."userId",
    "uvcv"."courseId",
    "uvcv"."videoId",
    CAST (null AS integer) AS "examId",
    "uvcv"."isComplete" AS "isComplete"
FROM public.video_completed_view AS "uvcv"
UNION ALL
SELECT 
    "uecv"."userId",
    "uecv"."courseId",
    CAST (null AS integer) AS "videoId",
    "uecv"."examId",
    "uecv"."isCompleted" AS "isComplete"
FROM public.user_exam_completed_view AS "uecv"
.
.

File name: "CourseItemStateView" which resolves to: "course_item_state_view" This DEPENDS on the "course_item_view", as you can see in the SQL

@ViewEntity({
    expression: `
SELECT 
    "course"."id" AS "courseId",
    "user"."id" AS "userId",
    "civ"."videoId" AS "videoId",
    "civ"."isComplete" AS "isVideoCompleted",
    "civ"."examId" AS "examId",
    "civ"."isComplete" AS "isExamCompleted"
    
FROM public."course"

LEFT JOIN public."user" 
ON 1 = 1

LEFT JOIN public.course_item_view AS "civ" ------------------- HERE
ON "civ"."courseId" = "course"."id"
    AND "civ"."userId" = "user"."id"

ORDER BY "civ"."videoId","civ"."examId"
`
})
.
.

My connection options:

const postgresOptions = {
        // properties, passwords etc...
        entities: [
           // entities....
           // ...
           // ...

            // views
            VideoCompletedView,
            UserExamCompletedView,
            UserExamAnswerSessionView,
            UserVideoMaxWatchedSecondsView,
            CourseItemView, --------------------------------HERE
            CourseItemStateView ---------------------------HERE
        ],
    } as ConnectionOptions;

createConnection(postgresOptions )

Steps to Reproduce

Create ViewEntites that depend on each other You will run into this issue, but is hard to say exactly why and when, this is the main problem.

like image 893
spenglermanfred Avatar asked Oct 15 '25 05:10

spenglermanfred


1 Answers

You can now define other views that the view entity depends on the ViewEntity decorator.


@ViewEntity({
    expression: `SELECT * FROM 1`,
    dependsOn:[CourseItemView]
})


From docs https://github.com/typeorm/typeorm/blob/abb9079f2b2c5e02253b4c83ba10358d1a1f373f/docs/view-entities.md#what-is-view-entity

@ViewEntity() accepts following options:

  • name - view name. If not specified, then view name is generated from entity class name.
  • database - database name in selected DB server.
  • schema - schema name.
  • expression - view definition. Required parameter.
  • dependsOn - List of other views on which the current views depends. If your view uses another view in it's definition, you can add it here so that migrations are generated in the correct order.
like image 128
Murage Avatar answered Oct 17 '25 13:10

Murage