繁体   English   中英

如何扩展 SQLAlchemy 的 association_proxy 的 getter 功能?

[英]How to extend the `getter`-functionality of SQLAlchemy's association_proxy?

编辑:我想 model UserComment之间的1 to 0:1关系(用户可以有零个或一个评论)。 我不想访问 object 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 拥有普通property你真的可以过得很好。 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

尝试这个

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)

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

  user_object = orm.relationship(
      "User",
      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()
  u = User(name="Max Mueller")
# comment = Comment("")
# comment.user_object = u

# session.add(u)
# session.commit()
  print "SS :", u
  print u.comment

你给uselistbackref必须处于relationship

我没有看到任何可以解决问题的答案,例如也可以使用“sort_by”。

也许使用“column_property”会更好,请参阅按关联代理排序:无效 sql

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM