【问题标题】:Updating a list of dicts filled by SQLAlchemy causes “object is not subscriptable” error更新由 SQLAlchemy 填充的字典列表会导致“对象不可下标”错误
【发布时间】:2016-12-25 15:15:44
【问题描述】:

我的 Flask-Restful Web 服务器有一个名为 mashrecipies 的字典列表。

mashrecipies = [
    {
        'id': 1,
        'name': 'Kölsch',
        'description': 'Top fermented ale from Köln'

    },
    {
        'id': 2,
        'name': 'IPA',
        'description': 'Classic British Imperial Pale Ale'
    },
]

我可以通过 Http PUT 服务从网络客户端成功更新字典。

我还可以使用 SQLAlchemy ORM 通过类 Mash 使用 SQLite DB 中的记录填充列表 mashrecipies

Base = declarative_base()

class Mash(Base):
    __tablename__ = 'mash'

    id = Column(Integer, primary_key=True)
    selected = Column(Boolean)
    name = Column(String)
    type = Column(String)
    description = Column(String)

    def __repr__(self):
        return '<{id}, {selected}, {name}, {type}, {desc}>'\
            .format(id=self.id, selected=self.selected, name=self.name, type=self.type, desc=self.description)
class Db():
    engine = create_engine(SQLALCHEMY_DATABASE_URI)
    Session = sessionmaker(bind=engine)
    session = Session()

def get_mashrecipies(self,):
    mashrecipies.clear()
    rec = None
    for rec in self.session.query(Mash).order_by(Mash.id):
        mashrecipies.append(rec)

但是,如果我使用 SQLAlchemy 填写了列表,然后尝试通过相同的 Http PUT 更新列表内容,我现在会收到错误:

文件 "/Users/xxx/PycharmProjects/AleSheep/server/apis/mashrecipesapi.py", 第 81 行,在 mashrecipe = [mashrecipies 中 mashrecipe 的 mashrecipe ['id'] == id] TypeError: 'Mash' object is not subscriptable

我的 Flask-Restful 资源中的 put 处理程序是:

def put(self, id):
    mashrecipe = [mashrecipe for mashrecipe in mashrecipies if mashrecipe['id'] == id]

mashrecipiesMash 之间的唯一显式链接(在我的代码中)是当我通过直接附加 SQLAlchemy 查询中的记录从 Mash 填充 mashrecipies 时。

如果我不做mashrecipies.append(rec),而是将字段复制到字典中,然后附加字典:

dict = {'id': rec.id, 'name': rec.name, 'description': rec.description}
mashrecipies.append(dict)

然后我的 PUT 服务再次正常工作。这解决了我眼前的问题。

但是用从 SQLAlchemy 查询中复制的字段的字典填充列表(OK)和直接附加从查询返回的记录(NOT OK)有什么区别?

SQLAlchemy 是否跟踪查询记录的更改,也许是为了持久化它们?

【问题讨论】:

    标签: python dictionary sqlalchemy


    【解决方案1】:

    根据错误文本,我认为您存储在 mashrecipe(Mash 类型)中的对象类型不可下标。也就是说,当您在实例上使用 [] 时,它没有 python 解释器调用的函数。例如,数组和列表是可下标的,并且确实具有此功能。

    要使对象可下标,您必须实现函数__getitem__(self, index)。当您使用(例如)mashrecipe["hello"] 时将调用它。第一个参数 (self) 是对象的实例,第二个参数 (index) 是您尝试访问的索引。该函数应该返回您期望的任何内容。

    看起来这个功能没有在你继承的类中实现,也没有在你的类中实现。因此,错误。

    在此处阅读有关__getitem__ 的更多信息 - http://www.diveintopython.net/object_oriented_framework/special_class_methods.html

    【讨论】:

    • 超级迪米特里!我没有点击该列表正在存储 Mash 的实例,现在您指出这一点很明显!如果我把[...mashrecipe[id] == id]改成[...mashrecipe.id == id],那么错误就不再出现了,也不需要在Mash类中添加__getitem__函数。
    • ..在其他人之前,我会链接这个SO question explaining the object types that are subscriptable
    猜你喜欢
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 2018-07-12
    • 1970-01-01
    • 2020-04-28
    • 2014-11-05
    • 1970-01-01
    • 2013-04-23
    相关资源
    最近更新 更多