将PostgreSQL的Enum与TypeDecorator相结合

4
有没有一种方法可以创建一个Enum类,在创建新的数据库时自动创建,就像标准的Enum一样,同时还可以将其连接到TypeDecorator,运行process_bind_param?
以下是第一个代码块,它创建了一个Enum类型,在保存之前自动将输入转换为小写,但与普通的Enum不同,特定的PostgreSQL枚举类型不会在数据库中自动创建,因此在创建表时运行create_all()会导致错误,因为language_code类型在PostgreSQL模式中不存在。
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.Enumsqlalchemy.dialects.postgresql.ENUM,但无论我做什么,我都会得到一个自动创建的类,或者一个运行process_bind_param的类,但永远不能同时拥有。

1个回答

2

这似乎可行,尽管如果有人知道更好的解决方案或发现问题,那将会更好。

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()

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