2016-08-18 62 views
0

My Flask-Restful Web服務器有一個名爲mashrecipies的字典列表。更新由SQLAlchemy填充的字典列表導致「object is not subcriptable」錯誤

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客戶端的類型的字典。

我還可以使用SQLAlchemy ORM通過類Mash填充列表mashrecipies與來自SQLite數據庫的記錄。

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更新列表內容,我現在得到的錯誤:

File "/Users/xxx/PycharmProjects/AleSheep/server/apis/mashrecipesapi.py", line 81, in mashrecipe = [mashrecipe for mashrecipe in mashrecipies if mashrecipe['id'] == id] TypeError: 'Mash' object is not subscriptable

認沽處理器在我Flask- REST的資源是:

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

mashrecipiesMash之間的唯一明確的鏈接(在我的代碼)是當我填寫mashrecipiesMash通過直接附加SQLAlchemy查詢中的記錄。

如果不是做mashrecipies.append(rec),我複製到領域的字典,並追加字典:

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

然後我PUT服務無差錯的作品一次。這解決了我眼前的問題。

但填充列表與字典與從SQLAlchemy查詢(確定)複製的字段和直接追加從查詢返回的記錄(不正確)之間有什麼區別?

SQLAlchemy跟蹤對查詢記錄的更改,可能是爲了保留它們嗎?

回答

1

根據錯誤文本,我認爲您存儲在mashrecipe(Mash類型)中的對象類型不是可以下載的。也就是說,它沒有python解釋器在實例上使用[]時調用的函數。例如,數組和列表是可下載的,並且具有此功能。

要使對象具有可訂閱性,您必須實現功能__getitem__(self, index)。它將在您使用時調用(例如)mashrecipe["hello"]。第一個參數(self)是對象的一個​​實例,第二個參數(index)是您嘗試訪問的索引。該函數應該返回你所期望的。

看起來好像這個功能沒有在你繼承的類中實現,並且它沒有在你的類中實現。因此,錯誤。

瞭解更多關於__getitem__在這裏 - http://www.diveintopython.net/object_oriented_framework/special_class_methods.html

+0

超級迪米特里!我沒有點擊該列表存儲Mash的實例,現在您明確指出了這一點!如果我將'[... mashrecipe [id] == id]'更改爲'[... mashrecipe.id == id]',那麼錯誤不再發生,並且不需要添加'__getitem__'函數到'Mash'類。 – FlyingSheep

+0

..和其他人之前,我會鏈接這個[SO問題解釋對象類型是可押腳](http://stackoverflow.com/questions/216972/in-python-what-does-it-mean-if -an-對象是-標化的 - 或不) – FlyingSheep