最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

postgresql - How to set up one-to-many relation with Drizzle - Stack Overflow

programmeradmin7浏览0评论

I have 2 tables/entities: Cases and Comments. A Case can have many Comments; a Comment can belong to one Case. I am trying to query Cases with Comments, as in:

  const caseData = await db.query.cases.findFirst({
    where: eq(Cases.id, id),
    with: {
      client: {
        with: {
          contacts: {
            with: {
              contact: true,
            },
          },
        },
      },
      property: {
        with: {
          contacts: {
            with: {
              contact: true,
            },
          },
        },
      },
      defendant: true,
      opposingCounsel: true,
      comments: true,
    },
  });

I am getting the error There is not enough information to infer relation "casesments".

I have followed the Drizzle documentation for one-to-many relations and SakuraDev's tutorial, which closely follows the Drizzle documentation. I have tried various solutions mentioned on S.O. I have tried using join tables (which seems ridiculous and isn't mentioned as required in the docs). I have tried adding relationName to both relations definitions (I've tried using both 'comments' and 'cases' here).

I am expecting this to send back a Case which includes an array with any associated Comments.

My Case table is:

export const Cases = pgTable(
  "cases",
  {
    id: integer().primaryKey().generatedAlwaysAsIdentity(),
    createdAt: timestamp({ withTimezone: true }).defaultNow(),
    updatedAt: timestamp({ withTimezone: true })
    .defaultNow()
    .$onUpdate(() => new Date()),

    [ . . . a bunch of other columns/fields . . . ]

  },
  (table) => ({ ...baseIndexes(table) })
);

The Case relations are:

export const CasesRelations = relations(Cases, ({ one, many }) => ({
  defendant: one(Defendants, {
    fields: [Cases.defendantId],
    references: [Defendants.id],
  }),
  property: one(Properties, {
    fields: [Cases.propertyId],
    references: [Properties.id],
  }),
  client: one(Clients, {
    fields: [Cases.clientId],
    references: [Clients.id],
  }),
  opposingCounsel: one(Contacts, {
    fields: [Cases.opposingCounselId],
    references: [Contacts.id],
  }),
  comments: many(Comments),
}));

My Comments table is:

export const Comments = pgTable(
  "comments",
  {
    id: integer().primaryKey().generatedAlwaysAsIdentity(),
    createdAt: timestamp({ withTimezone: true }).defaultNow(),
    updatedAt: timestamp({ withTimezone: true })
    .defaultNow()
    .$onUpdate(() => new Date()),

    caseId: integer().references(() => Cases.id),
    description: text(),
    type: text(),
  },
  (table) => ({ ...baseIndexes(table) })
);

The Comments relations are:

export const CommentsRelations = relations(Comments, ({ one }) => ({
  case: one(Cases, {
    fields: [Comments.caseId],
    references: [Cases.id],
  }),
}));

Related Case controllers:

caseRoutes.get("", async (req: Request, res: Response) => {
  const where: (SQL<unknown> | undefined)[] = [];
  [ . . . a bunch of values pulled off of the request query . . . ]

  [ . . . push those values to where . . . ]

  const search = req.query.search as string;
  if (search) {
    for (const term of search.split(" ")) {
      where.push(
        or(
          ilike(Cases.caseNumber, `%${term}%`),
          ilike(Clients.name, `%${term}%`),
          ilike(Defendants.firstName, `%${term}%`),
          ilike(Defendants.middleName, `%${term}%`),
          ilike(Defendants.lastName, `%${term}%`),
          ilike(Defendants.businessName, `%${term}%`),
          ilike(Defendants.address1, `%${term}%`),
          ilike(Defendants.address2, `%${term}%`),
          ilike(Defendants.city, `%${term}%`),
          ilike(Defendants.zip, `%${term}%`),
          ilike(Properties.name, `%${term}%`)
        )
      );
    }
  }

  const searchQuery = db
    .select({ id: Cases.id })
    .from(Cases)
    .leftJoin(Properties, eq(Cases.propertyId, Properties.id))
    .leftJoin(Clients, eq(Cases.clientId, Clients.id))
    .leftJoin(Defendants, eq(Cases.defendantId, Defendants.id))
    .leftJoin(Comments, eq(Cases.id, Comments.caseId))
    .where(and(...where));

  const casesConfig: DBQueryConfig = {
    limit,
    offset,
    orderBy: [desc(Cases.createdAt), desc(Cases.id)],
    where: inArray(Cases.id, searchQuery),
    with: {
      client: true,
      property: true,
      defendant: true,
      comments: true,
    },
  };

  const count = await db.$count(Cases, inArray(Cases.id, searchQuery));
  const cases = await db.query.cases.findMany(casesConfig);

  res.json({ cases, count });
});

caseRoutes.get("/:id", async (req: Request, res: Response) => {
  const id = Number(req.params.id);
  const decryptValues = req.query.decrypt === "true";

  if (!id) {
    res.status(404).json({ error: "Case not found" });
    return;
  }

  const caseData = await db.query.cases.findFirst({
    where: eq(Cases.id, id),
    with: {
      client: {
        with: {
          contacts: {
            with: {
              contact: true,
            },
          },
        },
      },
      property: {
        with: {
          contacts: {
            with: {
              contact: true,
            },
          },
        },
      },
      defendant: true,
      opposingCounsel: true,
      comments: true,
    },
  });

  if (decryptValues && caseData?.additionalDefendants?.length) {
    for (const additionalDefendant of caseData.additionalDefendants) {
      if (additionalDefendant.ssn) {
        additionalDefendant.ssn = await decrypt(additionalDefendant.ssn);
      }
    }
  }

  res.json(caseData);
});
发布评论

评论列表(0)

  1. 暂无评论