2015-07-03 3 views
4

Учитывая пару простых таблиц в sqlalchemy, которые имеют отношение простого к одному, я пытаюсь написать обобщенную функцию для добавления дочерних элементов в коллекцию отношений. Таблицы выглядеть следующим образом:Косвенный доступ к атрибуту экземпляра Python без использования точечной нотации

class StockItem(Base): 

    __tablename__ = 'stock_items' 

    stock_id = Column(Integer, primary_key=True) 
    description = Column(String, nullable=False, unique=True) 
    department = Column(String) 
    images = relationship('ImageKey', backref='stock_item', lazy='dynamic') 

    def __repr__(self): 
     return '<StockItem(Stock ID:{}, Description: {}, Department: {})>'.\ 
      format(self.stock_id, self.description, self.department) 


class ImageKey(Base): 

    __tablename__ = 'image_keys' 

    s3_key = Column(String, primary_key=True) 
    stock_id = Column(Integer, ForeignKey('stock_items.stock_id')) 

    def __repr__(self): 
     return '<ImageKey(AWS S3 Key: {}, Stock Item: {})>'.\ 
      format(self.s3_key, self.stock_id) 

Так что с данной установкой, я могу добавить элементы в images коллекции для данной StockItem:

item = StockItem(stock_id=42, description='Frobnistication for Foozlebars', 
       department='Books') 
image = ImageKey(s3_key='listings/images/Frob1.jpg', stock_id=42) 
item.images.append(image) 

Ok. Все идет нормально. На самом деле, мое приложение будет иметь несколько таблиц с отношениями. Моя проблема возникает, когда я пытаюсь обобщить это на функцию для обработки произвольных отношений. Here'e то, что я написал (обратите внимание, add_item() это просто метод, который обертывание строительства объекта с try/except для обработки IntegrityError iS):

@session_manager 
def _add_collection_item(self, Parent, Child, key, collection, 
         session=None, **kwargs): 
    """Add a Child object to the collection object of Parent.""" 
    child = self.add_item(Child, session=session, **kwargs) 
    parent = session.query(Parent).get(key) 
    parent.collection.append(child) # This line obviously throws error. 
    session.add(parent) 

Я называю функция, как:

db._add_collection_item(StockItem, ImageKey, 42, 'images', 
         s3_key='listings/images/Frob1.jpg', 
         stock_id=42) 

который очевидно, потому что родительская таблица не имеет атрибута collection. Traceback:

Traceback (most recent call last): 
    File "C:\Code\development\pyBay\demo1.py", line 25, in <module> 
    stock_id=1) 
    File "C:\Code\development\pyBay\pybay\database\client.py", line 67, in add_context_manager 
    result = func(self, *args, session=session, **kwargs) 
    File "C:\Code\development\pyBay\pybay\database\client.py", line 113, in _add_collection_item 
    parent.collection.append(child) 
AttributeError: 'StockItem' object has no attribute 'collection' 

Я думаю, что это будет сгенерировано сообщение об ошибке в любом случае, так как название коллекции передается в виде строки.

Итак, мой вопрос: как добавить элемент в коллекцию по ключевому слову, вместо того, чтобы использовать «точную» нотацию?

ответ

Смежные вопросы