更新SQLAlchemy填充的dicts列表会导致“object is not subscriptable”错误

时间:2016-08-18 15:44:51

标签: python dictionary sqlalchemy

我的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服务从Web客户端成功更新dicts。

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

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 = [mashrecipe for mashrecipe in mashreccipies mashrecipe ['id'] == id] TypeError:'Mash'对象不可订阅

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

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

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

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

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

然后我的PUT服务再次正常运行。这解决了我当前的问题。

但是,使用dicts填充列表与从SQLAlchemy查询(OK)复制的字段,并直接附加从查询返回的记录(NOT OK)之间有什么区别?

SQLAlchemy是否跟踪对查询记录的更改,也许是为了保留它们?

1 个答案:

答案 0 :(得分:1)

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

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

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

在此处详细了解__getitem__ - http://www.diveintopython.net/object_oriented_framework/special_class_methods.html