Altering a colum to an enum with useNative: true fails, tries to create enum twice
See original GitHub issueEnvironment
Knex version: 0.20.9 Database + version: Postgres 12 OS: Linux (Ubuntu)
Bug
If you attempt to alter a column to change it’s type to an enum, and you use the useNative: true
enum option, knex will try to create the enum twice, which causes a “type already exists” error.
Here is an example migration which demonstrates the problem:
export async function up(knex: Knex): Promise<any> {
return knex.schema
.debug(true)
.createTable("orders", (table) => {
table.text("drink");
})
.alterTable("orders", (table) => {
// This one works
table.enum("size", ["small", "medium", "large"], {
enumName: "drink_sizes",
useNative: true,
});
// This one tries to create the enum twice
table
.enum("drink", ["coffee", "tea", "water"], {
enumName: "drink_types",
useNative: true,
})
.alter();
});
}
If you look at the debug output from that migration, you will see that the first enum in the alterTable part generates the sql fine, but the second one (using .alter()
) will create two identical create type
sql statements, which causes Postgres to fail with ‘type “drink_types” already exists’
EDIT:
tl;dr Altering table to enum seems to try to create column type twice:
Issue Analytics
- State:
- Created 4 years ago
- Comments:10 (9 by maintainers)
Top Results From Across the Web
knex migration creat type for enum thows type already exists
Looks like there is a bug in knex which causes create type query to be added twice when altering columns like that.
Read more >MySQL 8.0 Reference Manual :: 11.3.5 The ENUM Type
An ENUM is a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column...
Read more >Postgres: Enum type fields | Hasura GraphQL Docs
You may use native Postgres enum types in your database schema, but they will essentially be treated like text fields in the generated...
Read more >Schema Builder | Knex.js
Creates a new table on the database, with a callback function to modify the table's ... null, { useNative: true, existingType: true, enumName:...
Read more >Enumerations - a free Hacking with Swift tutorial
If we make this an enum, it means Swift will accept only those five values – anything else will trigger an error. And...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
It sounds like a bad idea that
getColumnType()
creates that query as a side effect. Without looking the code to me it would make more sense to have createColumnType() and getColumnType() as a separate methods.But in this scenario I wouldn’t expect alter to delete the existing type, so that’s fine, I just don’t see why it is trying to create the type twice? This essentially makes it impossible to use
.enum()
with.alter()
if you’re using native enums.Is there any scenario where
.alter()
should create the type? It seems like the.enum()
part is responsible for that, so why does alter also try to do it?