python – 将PostgreSQL Enum与TypeDecorator结合使用

有没有办法让Enum类在创建新数据库时自动创建,比如标准枚举,还可以将它连接到运行process_bind_param的TypeDecorator?

第一个代码块创建一个Enum类型,在保存输入之前自动降低输入,但是,与普通的Enum不同,特定的PostgreSQL枚举类型不会在数据库中自动创建,因此在创建表时运行create_all()会导致错误,因为PostgreSQL架构中不存在language_code类型.

class LowercaseEnum(sqlalchemy.types.TypeDecorator):
    '''Converts input to lowercase.'''

    impl = sqlalchemy.types.Enum

    def process_bind_param(self, value, dialect):
        return value.lower()

class Foo(Model):
    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
    language_code = sqlalchemy.Column(LowercaseEnum(*['de', 'en'], name='language_code'))

另一方面,如果我在第二个代码块中定义我的自定义类型,那么它在调用create_all()时会自动创建,但是在向数据库发送值时从不调用process_bind_param方法,因此小写不会工作.

class LowercaseEnum(sqlalchemy.dialects.postgresql.ENUM, sqlalchemy.types.TypeDecorator):
    '''Converts input to lowercase.'''

    impl = sqlalchemy.types.Enum

    def process_bind_param(self, value, dialect):
        return value.lower()

我还尝试了几种不同的继承TypeDecorator的组合,它们是一个混合的单独类,并且还切换了sqlalchemy.types.Enum和sqlalchemy.dialects.postgresql.ENUM,但似乎无论我做什么,我要么得到一个自动创建的类,或者一个运行process_bind_param的类,但从不两者都有.

最佳答案 这似乎有效,但如果有人知道更好的解决方案或看到这个问题仍然会很好.

class LowercaseEnum(sqlalchemy.types.TypeDecorator, sqlalchemy.types.SchemaType):
    '''Converts input to lowercase.'''

    impl = sqlalchemy.dialects.postgresql.ENUM

    def _set_table(self, table, column):
        self.impl._set_table(table, column)

    def process_bind_param(self, value, dialect):
        return value.lower()
点赞