SQLAlchemy / PostgreSQL可变,重复数据删除阵列

时间:2015-04-24 16:52:16

标签: python arrays postgresql sqlalchemy mutable

在阅读了article关于使用PostgreSQL实现标签之后,我决定使用PostgreSQL的数组数据类型。

但据我所知,SQLAlchemy中没有对可变数组的内置支持。我还想防止这些数组中的重复(在PostgreSQL中没有任何内置的'类似数据类型)。

我很难找到如何使用和操作由PostgreSQL支持的SQLAlchemy数组(声明性地)的具体示例,即使对于简单的追加/更新操作也是如此。如何设置ARRAY并追加到(如果要附加的字符串不是重复的)SQLAlchemy ARRAY数据类型?

1 个答案:

答案 0 :(得分:3)

我遇到了这个问题。我使用的解决方案是创建一个继承自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))

这会覆盖set的方法,它可以通过添加对Mutable的{​​{1}}方法的调用来更改集合的值,从而导致SQLAlchemy将可能更改的值刷新到数据库。

然后,在SQLAlchemy中声明此类型,其类型将在其中;例如,将其声明为一组整数:

changed

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