drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
22k stars 508 forks source link

[BUG]: Modifying a column causes WARNING DATA LOSS #2047

Open pironti opened 4 months ago

pironti commented 4 months ago

What version of drizzle-orm are you using?

0.29.4

What version of drizzle-kit are you using?

0.20.14

Describe the Bug

When I change a column in the schema and then run the ‘drizzle-kit push:mysql’ command, I receive an error message saying that the migration will cause data loss.”

Schema File

image

I altered de column user_id from varchar(28) to varchar(30)

Warning message:

image

THIS ACTION WILL CAUSE DATA LOSS AND CANNOT BE REVERTED

Do you still want to push changes? ❯ No, abort Yes, I want to truncate 1 table

Expected behavior

The expected behavior was for the migration to be executed without requesting user action. I understand this to be a bug, as this migration does not cause any side effects on the database since the column was already nullable, and when I run the generated SQL directly on the database, no errors occur.

As shown:

Generated migration:

image

Running the generated SQL directly on the database:

image

Environment & setup

Create schema:

export const assistants = mysqlTable(
    "assistants",
    {
        id: varchar("id", { length: 29 })
            .notNull()
            .primaryKey()
            .$defaultFn(() => createPrimaryKey("asst")),
        abilities: json("abilities")
            .$type<string[]>()
            .default([AssistantAbilities["TEXT"]]),
        promptExamples: json("examples_prompt")
            .$type<{ id: string; text: string }[]>()
            .default([]),
        createdBy: varchar("user_id", { length: 28 }).references(
            () => users.id,
            { onDelete: "set null" },
        ),
        createdAt: timestamp("created_at").defaultNow(),
        updatedAt: timestamp("updated_at").defaultNow().onUpdateNow(),
    },
    (t) => ({
        nameOrganizationUnique: unique().on(t.organizationId, t.name),
    }),
);

Run commands:

npx drizzle-kit generate:mysql npx drizzle-kit push:mysql

Alter schema:

export const assistants = mysqlTable(
    "assistants",
    {
        id: varchar("id", { length: 29 })
            .notNull()
            .primaryKey()
            .$defaultFn(() => createPrimaryKey("asst")),
        abilities: json("abilities")
            .$type<string[]>()
            .default([AssistantAbilities["TEXT"]]),
        promptExamples: json("examples_prompt")
            .$type<{ id: string; text: string }[]>()
            .default([]),
        createdBy: varchar("user_id", { length: 30 }).references(
            () => users.id,
            { onDelete: "set null" },
        ),
        createdAt: timestamp("created_at").defaultNow(),
        updatedAt: timestamp("updated_at").defaultNow().onUpdateNow(),
    },
    (t) => ({
        nameOrganizationUnique: unique().on(t.organizationId, t.name),
    }),
);

Run commands:

npx drizzle-kit generate:mysql npx drizzle-kit push:mysql

CestDiego commented 2 months ago

I get the same issue. Whenever I try to do a push it does this.

truncate table <table> cascade;

MishellSossa commented 2 months ago

Same Issue here, exactly doing the same process as the Original Poster. The problem seems to be in the push command. Running the migrations using the migrate function (Node.JS) does not cause the same issue.

cb1kenobi commented 2 months ago

I'm running into this issue. This is a huge problem. There's no reason to truncate the table when making certain changes to a table. If I change a column type from enum to varchar, allow a column to be null, or set a default value, those are all changes that the database can handle without data loss.

I have to manually run the migration and that's not great.