python - 如何扩展SQLAlchemy的association_proxy的 `getter`功能?

标签 python proxy sqlalchemy

编辑:我想在用户评论之间建立一个1到0:1关系模型(一个用户可以有零个或一个评论)。我宁愿直接访问评论本身,而不是访问对象 Comment。使用 SQLAlchemys association_proxy 非常适合该场景除了一件事:在关联 Comment 之前访问 User.comment 。但在这种情况下,我宁愿期望 None 而不是 AttributeError 作为结果。

看下面的例子:

import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy import Column, Integer, Text, ForeignKey, Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy

Base = declarative_base()

class User(Base):
  __tablename__ = 'users'
  id = Column(Integer, primary_key=True)
  name = Column(Text)

  def __init__(self, name):
      self.name = name

  # proxy the 'comment' attribute from the 'comment_object' relationship
  comment = association_proxy('comment_object', 'comment')


class Comment(Base):
  __tablename__ = 'comments'
  id = Column(Integer, primary_key=True)
  comment = Column('comment', Text, nullable=False, default="")
  user_id = Column(ForeignKey('users.id'), nullable=False, unique=True)
  # user_id has to be unique to ensure that a User can not have more than one comments

  def __init__(self, comment):
      self.comment = comment

  user_object = orm.relationship(
      "User",
      uselist=False, # added after edditing the question
      backref=orm.backref('comment_object', uselist=False)
      )

if __name__ == "__main__":
  engine = sa.create_engine('sqlite:///:memory:', echo=True)
  Session = orm.sessionmaker(bind=engine)
  Base.metadata.create_all(engine)
  session = Session()

现在,以下代码抛出 AttributeError:

u = User(name="Max Mueller")
print u.comment

捕获该异常并提供默认值(如空字符串)的最佳方法是什么?

最佳答案

您实际上并不需要 association_proxy 为此。使用常规属性确实可以过得很好。 AttributeError 的原因(可能)是因为 comment_object 本身是 None,因为没有依赖行,并且 None 没有 comment 属性。

class User(Base):
  __tablename__ = 'users'
  id = Column(Integer, primary_key=True)
  name = Column(Text)

  def __init__(self, name):
      self.name = name

  # proxy the 'comment' attribute from the 'comment_object' relationship
  @property
  def comment(self):
      if self.comment_object is None:
          return ""
      else:
          return self.comment_object.comment

  @comment.setter
  def comment(self, value):
      if self.comment_object is None:
          self.comment_object = Comment()
      self.comment_object.comment = value

关于python - 如何扩展SQLAlchemy的association_proxy的 `getter`功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9063478/

相关文章:

c - gethostbyname,连接到整个互联网?

Java 动态代理 - 如何引用具体类

python - sqlalchemy更新bindparam主键

python - Flask-Admin 在更新时删除辅助映射

python - Python中Stata宏的等价物

python - 迭代时从列表中删除

python - 找到数组或列表中最密集区域的最快方法是什么?

wcf - 在 IClientChannel 代理上调用 Abort() 会抛出异常吗?

Python数据帧: labelling (1-0) ) adjacent rows upon condition

python - 在 Pyramid 中存储和验证用于登录的加密密码