4

有没有办法让一个 Enum 类在创建新数据库时自动创建,如标准 Enum,但也将它连接到TypeDecorator运行process_bind_param

这第一个代码块创建了一个Enum在保存之前自动将输入小写的类型,但是,与普通Enum的 PostgreSQL 不同的是,特定的 PostgreSQL 枚举类型不是在数据库中自动创建的,因此create_all()在创建表时运行 a 会导致错误,因为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.Enumand sqlalchemy.dialects.postgresql.ENUM,但似乎无论我做什么,我要么得到一个自动创建的类,要么得到一个运行的类process_bind_param,但从不两者兼而有之。

4

1 回答 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()
于 2013-06-04T23:06:54.293 回答