Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the data type of a table column to enum?

I have a table "ENGINE" in a Postgres DB, in which I have to change the datatype of a column named loglevel from string to enum.

However, I am not able to understand instructions in the manual:

ALTER [ COLUMN ] column TYPE type [ USING expression ]
like image 527
shashank Avatar asked Jul 05 '17 22:07

shashank


People also ask

How do I create an enum column in SQL Server?

In MySQL one can create an enum as such: USE WorldofWarcraft; CREATE TABLE [users] ( ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY, username varchar(255), password varchar(255), mail varchar (255), rank ENUM ('Fresh meat', 'Intern','Janitor','Lieutenant','Supreme being')DEFAULT 'Fresh meat', );

How can I change enum in SQL?

You can add a new value to a column of data type enum using ALTER MODIFY command. If you want the existing value of enum, then you need to manually write the existing enum value at the time of adding a new value to column of data type enum.

Is enum a data type in SQL?

An ENUM is a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column specification at table creation time. See Section 11.3. 1, “String Data Type Syntax” for ENUM type syntax and length limits.

What is enum data type in database?

Enumerated (enum) types are data types that comprise a static, ordered set of values. They are equivalent to the enum types supported in a number of programming languages. An example of an enum type might be the days of the week, or a set of status values for a piece of data.


1 Answers

enum is not a data type per se. It's a class of data types. (Generally, you can replace any enum with a FK column to a 1:n table.) And "string" is not a data type at all in Postgres. I assume we are talking about text or varchar? If so, these are the steps for your task:

1.) Create new enum type if it does not exist, yet. Let's call it loglevel. It has to include all distinct values from your string column or the type cast will fail. This DO command takes care of it:

DO
$$
BEGIN
EXECUTE (
   SELECT 'CREATE TYPE loglevel AS ENUM (' 
        || string_agg(quote_literal(loglevel), ', ')
        || ')'
   FROM  (
      SELECT loglevel
      FROM   "ENGINE"
      WHERE  loglevel IS NOT NULL  -- exclude NULL if present
      GROUP  BY 1
      ORDER  BY 1
      ) sub
   );
END
$$;

We have to exclude NULL if present, that cannot be listed as enum value. (Any enum type can be NULL anyway.)

Related:

  • Algebraic Data Types in Postgres

2.) Change the data type of the column:

You have to specify USING loglevel::loglevel explicitely, since there is no implicit cast between any string type (text, varchar?) and the new enum data type:

ALTER TABLE "ENGINE" ALTER loglevel TYPE loglevel USING loglevel::loglevel;

Details:

  • Rails Migrations: tried to change the type of column from string to integer
like image 66
Erwin Brandstetter Avatar answered Sep 27 '22 21:09

Erwin Brandstetter