drizzle-team / drizzle-kit-mirror

Docs and issues repository for drizzle-kit
287 stars 16 forks source link

TypeError: Cannot read properties of undefined (reading 'compositePrimaryKeys') #261

Open adamwilkins01 opened 7 months ago

adamwilkins01 commented 7 months ago

happened after trying to push to planetscale after resolving all column conflicts.

full error:


TypeError: Cannot read properties of undefined (reading 'compositePrimaryKeys')
    at D:\work\outreach-digital-media\node_modules\drizzle-kit\bin.cjs:17258:51
    at Array.map (<anonymous>)
    at prepareDeleteCompositePrimaryKeyMySql (D:\work\outreach-digital-media\node_modules\drizzle-kit\bin.cjs:17253:33)
    at D:\work\outreach-digital-media\node_modules\drizzle-kit\bin.cjs:17643:33
    at Array.forEach (<anonymous>)
    at applySnapshotsDiff (D:\work\outreach-digital-media\node_modules\drizzle-kit\bin.cjs:17571:26)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async prepareSQL (D:\work\outreach-digital-media\node_modules\drizzle-kit\bin.cjs:15174:14)
    at async prepareMySQLPush (D:\work\outreach-digital-media\node_modules\drizzle-kit\bin.cjs:14974:47)
    at async Command.<anonymous> (D:\work\outreach-digital-media\node_modules\drizzle-kit\bin.cjs:62995:22)
``
Bogdan-101 commented 7 months ago

Could you send your environment details (npm version, node version, version of drizzle-orm and drizzle-kit) and the table schema where you are trying to set a composite primary key?

bhlox commented 5 months ago

@Bogdan-101 Encountered the same issue when executing the commands drizzle-kit generate:pg and drizzle-kit push:pg

NPM: v9.8.0 Node: v20.10.0 drizzle-orm: v^0.29.3 drizzle-kit: v^0.20.10-3c347a7

export const categories = pgTable("categories", {
  // You can use { mode: "bigint" } if numbers are exceeding js number limitations
  id: bigint("id", { mode: "number" }).primaryKey().notNull(),
  name: varchar("name").notNull().unique(),
});

export const items = pgTable("items", {
  id: serial("id").primaryKey().notNull(),
  title: varchar("title", { length: 255 }).notNull(),
  price: numeric("price", { precision: 10, scale: 2 }).notNull(),
  imageLink: text("image_link").notNull().unique(),
  categoryId: integer("category_id").references(() => categories.id),
});

export const brands = pgTable("brands", {
  id: serial("id").primaryKey().notNull(),
  name: varchar("name", { length: 255 }).notNull().unique(),
  logo: text("logo").notNull().unique(),
});

export const brandsCategories = pgTable(
  "brands_categories",
  {
    brandId: integer("brand_id")
      .notNull()
      .references(() => brands.id),
    categoryId: integer("category_id")
      .notNull()
      .references(() => categories.id),
  },
  (table) => {
    return {
      entitycategoriesPkey: primaryKey({
        columns: [table.brandId, table.categoryId],
        name: "brand_categories_pkey",
      }),
    };
  }
);
ryantbrown commented 3 months ago

I also run into this same error when attempting to rename tables (using Planetscale). Here is an example stack trace:

--- all table conflicts resolved ---

TypeError: Cannot read properties of undefined (reading 'compositePrimaryKeys')
    at node_modules/drizzle-kit/bin.cjs:17175:51
    at Array.map (<anonymous>)
    at prepareDeleteCompositePrimaryKeyMySql (node_modules/drizzle-kit/bin.cjs:17170:33)
    at node_modules/drizzle-kit/bin.cjs:17560:33
    at Array.forEach (<anonymous>)
    at applySnapshotsDiff (node_modules/drizzle-kit/bin.cjs:17488:26)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async prepareSQL (node_modules/drizzle-kit/bin.cjs:15055:14)
    at async prepareMySQLPush (node_modules/drizzle-kit/bin.cjs:14863:47)
    at async Command.<anonymous> (node_modules/drizzle-kit/bin.cjs:63070:22)

[i] No changes detected

drizzle-kit: ^0.20.14 node: v20.10.0

steve-taylor commented 2 months ago

I get the same error when attempting to generate migrations that rename some tables and columns.

Thanks to this bug, I can't generate migrations at all.

I would create a pull request to fix this if Drizzle Kit was open source

steve-taylor commented 2 months ago

I narrowed this down to renaming a table that has a composite primary key, in my case using PostgreSQL.

Here's the offending bundled code from line 17,261 (because the source isn't available):

    prepareDeleteCompositePrimaryKeyPg = (tableName, schema5, pks, json1) => {
      return Object.values(pks).map((it) => {
        return {
          type: "delete_composite_pk",
          tableName,
          data: it,
          schema: schema5,
          constraintName: json1.tables[tableName].compositePrimaryKeys[PgSquasher.unsquashPK(it).name].name
        };
      });
    };

I found that tableName is the new name of the table, whereas json1.tables is keyed on the old table names. I think that in this scenario, tableName should be the old name of the table because that would be the correct name to use when deleting the composite primary key.

Tracing it back to the caller:

            deletedCompositePKs = prepareDeleteCompositePrimaryKeyPg(
              it.name,
              schemaUnwrapped,
              it.deletedCompositePKs,
              prevFull
            );

it is the table and name contains the current name. it has all sorts of info about what's been modified, but unfortunately it doesn't contain the previous name of the table. However, I found that rTables a bit further up has what I need, so I changed the above code snippet to this:

            const prevTableName = rTables.find(({to}) => to.name === it.name)?.from.name

            deletedCompositePKs = prepareDeleteCompositePrimaryKeyPg(
              prevTableName ?? it.name,
              schemaUnwrapped,
              it.deletedCompositePKs,
              prevFull
            );

and I was able to generate the migration somewhat successfully, the problem now being that the ALTER TABLE statements still refer to the old table, which is easy enough for me to manually fix. With a bit more hacking, I'm sure I could come up with a more complete solution, but since the source isn't available, there won't be much point.

@AndriiSherman I hope this information can help you fix this bug.

thebjorn commented 2 weeks ago

In version 0.31.2 I had to change ${schema5} to ${schema5 || "public"} in the prepareDeleteCompositePrimaryKeyPg function, line 27627 of bin.cjs:

    prepareDeleteCompositePrimaryKeyPg = (tableName, schema5, pks, json1) => {
      return Object.values(pks).map((it) => {
        return {
          type: "delete_composite_pk",
          tableName,
          data: it,
          schema: schema5,
          constraintName: json1.tables[`${schema5 || "public"}.${tableName}`].compositePrimaryKeys[PgSquasher.unsquashPK(it).name].name
        };
      });
    };

making the source available so we could provide useful PRs would be a great idea (even if you don't open-source license it).