【问题标题】:SQLAlchemy/PostgreSQL mutable, deduplicated arraySQLAlchemy/PostgreSQL 可变、去重数组
【发布时间】:2015-07-03 09:28:38
【问题描述】:

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

但据我了解,SQLAlchemy 中没有对可变数组的任何内置支持。我还想防止这些数组中出现重复(PostgreSQL 中没有任何内置的“set-like”数据类型)。

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

【问题讨论】:

    标签: python arrays postgresql sqlalchemy mutable


    【解决方案1】:

    我遇到了这个问题。我使用的解决方案是创建一个从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 的方法,这些方法可以通过添加对Mutablechanged 方法的调用来更改集合的值,从而导致SQLAlchemy 将可能更改的值刷新到数据库中。

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

    Column(ArraySet(Integer))
    

    然后,当你使用它时,你可以像对待一个标准的 Python 集合一样对待这个值,所有的操作符和方法都不变。

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 2012-12-22
      • 1970-01-01
      • 1970-01-01
      • 2019-06-05
      • 2019-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多