【问题标题】:How to get dict of lists from relationship in sqlalchemy?如何从 sqlalchemy 中的关系中获取列表的字典?
【发布时间】:2016-12-10 07:08:24
【问题描述】:

我发现您可以在关系中使用集合来更改返回值的类型,特别是我对字典感兴趣。 文档给出了example

class Item(Base):
    __tablename__ = 'item'
    id = Column(Integer, primary_key=True)
    notes = relationship("Note",
                         collection_class=attribute_mapped_collection('keyword'),
                         cascade="all, delete-orphan")

class Note(Base):
    __tablename__ = 'note'
    id = Column(Integer, primary_key=True)
    item_id = Column(Integer, ForeignKey('item.id'), nullable=False)
    keyword = Column(String)
    text = Column(String)

而且它有效。但是,我希望如果有不止一个具有相同名称的键,它将生成列表值。但它只将最后一个值放在唯一键名下。

这是一个例子:

|               Note table               |
|---------------------|------------------|
|          id         |      keyword     |
|---------------------|------------------|
|          1          |        foo       |
|---------------------|------------------|
|          2          |        foo       |
|---------------------|------------------|
|          3          |        bar       |
|---------------------|------------------|
|          4          |        bar       |
|---------------------|------------------|

item.notes 将返回如下内容:

{'foo': <project.models.note.Note at 0x7fc6840fadd2>,
 'bar': <project.models.note.Note at 0x7fc6840fadd4>}

其中 foo 和 bar 对象的 id 分别为 2 和 4。

我正在寻找的是得到这样的东西:

{'foo': [<project.models.note.Note at 0x7fc6840fadd1,
          <project.models.note.Note at 0x7fc6840fadd2>],
 'bar': [<project.models.note.Note at 0x7fc6840fadd3>,
         <project.models.note.Note at 0x7fc6840fadd4>]}

是否可以从 sqlalchemy 中的关系中获取列表的字典?

【问题讨论】:

  • 请修正缩进并给出输入输出示例
  • 已编辑:添加示例并修复缩进

标签: python dictionary sqlalchemy relationship


【解决方案1】:

所以,事实证明你可以简单地继承 MappedCollection 并在 setitem 中做任何你喜欢的事情。

from sqlalchemy.orm.collections import (MappedCollection,
                                        _SerializableAttrGetter,
                                        collection,
                                        _instrument_class)

#This will ensure that the MappedCollection has been properly 
#initialized with custom __setitem__() and __delitem__() methods 
#before used in a custom subclass
_instrument_class(MappedCollection)


class DictOfListsCollection(MappedCollection):

    @collection.internally_instrumented
    def __setitem__(self, key, value, _sa_initiator=None):
        if not super(DictOfListsCollection, self).get(key):
            super(DictOfListsCollection, self).__setitem__(key, [], _sa_initiator)
        super(DictOfListsCollection, self).__getitem__(key).append(value)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-03-26
  • 2017-05-25
  • 2018-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-18
  • 1970-01-01
相关资源
最近更新 更多