【问题标题】:ENUM type in SQLAlchemy with PostgreSQL使用 PostgreSQL 在 SQLAlchemy 中输入 ENUM
【发布时间】:2015-05-07 18:58:39
【问题描述】:

我将SQLAlchemy core 与postgresql 数据库一起使用,我想将ENUM 类型添加到我的表定义中。根据postgresql documentation,必须在创建表之前定义ENUM类型:

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

CREATE TABLE person (
  name VARCHAR(20),
  gender gender_enum
);

问题出在我创建表定义时。阅读SQLAlchemy documentation 后,我找不到任何实现示例。我已经尝试过类似的方法,但没有成功:

from sqlalchemy.dialects.postgresql import ENUM

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

必须怎么做?

【问题讨论】:

    标签: postgresql enums sqlalchemy


    【解决方案1】:

    您需要从 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))
    );
    

    【讨论】:

    • 为了让我使用 postgres,我必须 from sqlalchemy.dialects.postgresql import ENUM
    • 那是什么? OP 说postgreql.ENUM 不起作用,评论说它确实起作用。是否存在导致差异的版本或驱动程序差异?
    • 为什么:create_type=False?
    • create_type 在这里实际上没有用 - 那是 sqlalchemy.dialects.postgresql.ENUM。简而言之 - 如果您想在create_table 命令期间定义枚举类型并创建它,请使用sqlalchemy.Enum。如果您想在创建过程中为新表使用现有类型,请使用 dialects.postgresql.ENUMcreate_type = False
    • 如果有人使用特定的模式,我会遇到同样的问题,我可以使用from sqlalchemy import Enum 解决它,并且对于模式,我可以将schema=<schema_name> 传递给EnumEnum 类型文档:docs.sqlalchemy.org/en/13/core/…
    【解决方案2】:

    @Tim 的回答绝对正确,但我想提供我设置 ENUM 的方式。

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

    skill_levels = ('Zero', 'A little', 'Some', 'A lot')

    然后我将创建一个 Skill_level_enum 变量并为其分配一个 ENUM 类,并将技能级别值作为 args。

    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)
    

    我发现这使我的代码更加简洁,并且我能够对文件顶部的技能级别进行更新,而不是扫描我的模型以查找要更新的正确内容。

    【讨论】:

    • 没错,你可以定义一次枚举,然后在任何你需要的地方使用它。
    【解决方案3】:

    您也可以使用Python's native enums 作为列类型:

    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)
    

    【讨论】:

      【解决方案4】:

      下面的代码在 SQLAlchemy 1.3.11 和 Postgres 12.0 上为我工作。

      在创建用户表之前,必须先在 postgres 中创建 Enum 类型。这可以直接通过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"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-11
        • 2019-05-18
        • 1970-01-01
        • 2013-08-19
        • 1970-01-01
        • 1970-01-01
        • 2018-01-04
        • 1970-01-01
        相关资源
        最近更新 更多