SQLAlchemy中的ENUM类型与PostgreSQL

41

我正在使用SQLAlchemy核心与postgresql数据库,并且我想在我的表定义中添加ENUM类型。根据postgresql文档,必须在创建表之前定义ENUM类型:

CREATE TYPE gender_enum AS ENUM ('female', 'male');

CREATE TABLE person (
  name VARCHAR(20),
  gender gender_enum
);
问题在于我正在创建表定义时。在阅读了SQLAlchemy文档后,我没有找到任何实现示例。我尝试了像这样的东西,但它没有起作用:
from sqlalchemy.dialects.postgresql import ENUM

person = Table('user_profile', metadata,
    Column('name', String(20)),
    Column('gender', ENUM('female', 'male'))
);

怎样完成这件事?

4个回答

45
你需要从sqlalchemy导入Enum并给它添加一个名称。它应该像这样工作:

你需要从sqlalchemy导入Enum并给它添加一个名称。它应该像这样工作:

from sqlalchemy import Enum

person = Table("user_profile", metadata,
    Column("name", String(20)),
    Column("gender", Enum("female", "male", name="gender_enum", create_type=False))
);

17
为了让我在Postgres上工作,我必须使用from sqlalchemy.dialects.postgresql import ENUM - miah
1
那到底是怎么回事?OP 说 postgreql.ENUM 不好使,但评论里又说可以。是不是因为版本或驱动的不同导致了这个矛盾呢? - dwanderson
7
为什么要使用 create_type=False 参数? - Hans Bouwmeester
9
这里实际上用不到 create_type,它是针对 sqlalchemy.dialects.postgresql.ENUM 的。简而言之,如果你想在 create_table 命令期间定义并创建枚举类型,请使用 sqlalchemy.Enum。如果你想在创建新表时使用现有类型,请使用 dialects.postgresql.ENUM 并将 create_type = False - kevlarr
1
如果有人正在使用特定的模式,我也遇到了同样的问题,我能够通过使用 from sqlalchemy import Enum来解决它,并且对于模式,我可以将schema=<schema_name>传递给 EnumEnum类型文档: https://docs.sqlalchemy.org/en/13/core/type_basics.html#sqlalchemy.types.Enum.__init__ - lv10
谢谢@lv10 - 在枚举中添加schema=<schema_name>对我很有帮助:对于表的创建,它现在会正确地发出CREATE TYPE命令。 - Robert Muil

38

@Tim的答案肯定是正确的,但我想提供一下我设置枚举的方法。

在我的models.py文件中,我会将值创建为元组

skill_levels = ('零', '一点', '有些', '很多')

接着我会创建一个skill_level_enum变量,并将其赋值为一个ENUM类,其中参数是技能等级值的元组。

skill_level_enum = ENUM(*skill_levels, name="skill_level")

在我的表模型中,我将skill_level_enum传递进去。

class User(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    skill_level = db.Column(skill_level_enum)

我发现这样可以使我的代码更加简洁,我可以在文件顶部更新skill_levels而不是扫描我的模型以查找要更新的内容。


1
没错,你可以定义枚举一次,然后在需要的任何地方使用它。 - m1yag1

12

你可以使用Python 原生的枚举类型作为列类型:

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.dialects.postgresql import ENUM as pgEnum
from enum import Enum, unique

@unique
class errorTypeEnum(Enum):
    videoValidation = 'videoValidation'
    audioValidation = 'audioValidation'
    subtitleValidation = 'subtitleValidation'

db = SQLAlchemy()

class Error(db.Model):
    serviceID = db.Column(db.String(20), primary_key=True)
    timestamp = db.Column(db.DateTime, unique=False, nullable=False)
    category = db.Column(pgEnum(errorTypeEnum), unique=False, nullable=False)

3

以下代码适用于SQLAlchemy 1.3.11和Postgres 12.0。

在创建用户表之前,您必须先在Postgres中创建枚举类型。这可以通过SQL语句直接完成。

CREATE TYPE permission AS ENUM ('READ_ONLY', 'READ_WRITE', 'ADMIN', 'OWNER');

然后设置项目模型

from flask_sqlalchemy import SQLAlchemy    

db = SQLAlchemy()

class User(db.Model): 
    __tablename__ = 'user'

    user_id = db.Column(db.Integer, primary_key=True)   
    username = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)
    access = db.Column(db.Enum('READ_ONLY', 'READ_WRITE', 'ADMIN', 'OWNER', name="permission"))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接