SQLAlchemy/PostgreSQL 可变、去重数组

3
阅读完这篇关于使用PostgreSQL实现标签的文章之后,我决定使用PostgreSQL的数组数据类型。
但据我了解,在SQLAlchemy中没有内置支持可变数组的功能。我还想在这些数组中防止重复值(在PostgreSQL中也没有内置的类似“set”的数据类型)。
我很难找到任何有关如何使用和操作由PostgreSQL支持的SQLAlchemy数组(声明式地进行简单的追加/更新操作)的具体示例。如果要追加的字符串不是重复项,我该如何设置ARRAY并追加到SQLAlchemy ARRAY数据类型中?
1个回答

5

我曾经遇到过完全相同的问题。我的解决方法是创建一个继承自sqlalchemy.ext.mutable.Mutableset的类型,然后将其包装在一个由sqlalchemy.dialects.postgresql.ARRAY支持的类型中。

from sqlalchemy.ext.mutable import Mutable
from sqlalchemy.dialects.postgresql import ARRAY

modmethods = ['add', 'clear', 'difference_update', 'discard', 
              'intersection_update', 'pop', 'remove',
              'symmetric_difference_update', 'update',
              '__ior__', '__iand__', '__isub__', '__ixor__']

class MutableSet(Mutable, set):
    @classmethod
    def coerce(cls, key, value):
        if not isinstance(value, cls):
            return cls(value)
        else:
            return value

def _make_mm(mmname):
    def mm(self, *args, **kwargs):
        try:
            retval = getattr(set, mmname)(self, *args, **kwargs)
        finally:
            self.changed()
        return retval
    return mm

for m in modmethods:
    setattr(MutableSet, m, _make_mm(m))

del modmethods, _make_mm

def ArraySet(_type, dimensions=1):
    return MutableSet.as_mutable(ARRAY(_type, dimensions=dimensions))

这将覆盖可以通过添加对 Mutablechanged 方法的调用来更改集合值的 set 方法,导致SQLAlchemy将可能已更改的值刷新到数据库。
然后,在SQLAlchemy中使用将位于其中的类型声明此类型;例如,将其声明为整数集合:
Column(ArraySet(Integer))

然后,当您使用它时,您可以像标准的Python set一样处理该值,所有运算符和方法都不变。


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