不使用点表示法间接访问 Python 实例属性
Indirectly accessing Python instance attribute without using dot notation
鉴于 sqlalchemy
中的几个简单的 table 具有简单的一对多关系,我正在尝试编写一个通用函数来将子项添加到关系集合中。 table 看起来像这样:
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)
因此,通过给定的设置,我可以将项目添加到给定 StockItem
的 images
集合中:
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)
好的。到目前为止,一切都很好。实际上,我的应用程序将有多个 table 具有关系。当我尝试将其概括为处理任意关系的函数时,我的问题就出现了。这是我写的(注意,add_item()
只是一个用 try/except
包装对象构造以处理 IntegrityError
的方法):
@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)
这显然是错误的,因为父 table 没有 collection
属性。回溯:
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'
我认为它无论如何都会抛出错误,因为集合名称是作为字符串传递的。
所以我的问题是,如何通过关键字而不是使用 'dot' 符号将项目添加到集合中?
做:
getattr(parent, collection).append(child)
更多信息
鉴于 sqlalchemy
中的几个简单的 table 具有简单的一对多关系,我正在尝试编写一个通用函数来将子项添加到关系集合中。 table 看起来像这样:
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)
因此,通过给定的设置,我可以将项目添加到给定 StockItem
的 images
集合中:
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)
好的。到目前为止,一切都很好。实际上,我的应用程序将有多个 table 具有关系。当我尝试将其概括为处理任意关系的函数时,我的问题就出现了。这是我写的(注意,add_item()
只是一个用 try/except
包装对象构造以处理 IntegrityError
的方法):
@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)
这显然是错误的,因为父 table 没有 collection
属性。回溯:
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'
我认为它无论如何都会抛出错误,因为集合名称是作为字符串传递的。
所以我的问题是,如何通过关键字而不是使用 'dot' 符号将项目添加到集合中?
做:
getattr(parent, collection).append(child)
更多信息