如何扩展SQLAlchemy 的association_proxy 的`getter` 功能? [英] How to extend the `getter`-functionality of SQLAlchemy's association_proxy?
问题描述
我想对 User
和 Comment
之间的 1 to 0:1
关系建模(一个用户可以有零个或一个评论).我宁愿直接访问评论本身,而不是访问对象 Comment
.使用 SQLAlchemys association_proxy
非常适合该场景除了 一件事:在关联 Comment
之前访问 User.comment
.但在这种情况下,我宁愿期望 None
而不是 AttributeError
作为结果.
I would like to model a 1 to 0:1
relationship between User
and Comment
(a User can have zero or one Comment). Instead of accessing the object Comment
I would rather directly access the comment itself. Using SQLAlchemys association_proxy
works perfect for that scenario except for one thing: accessing User.comment
before having a Comment
associated. But in this case I would rather expect None
instead of AttributeError
as result.
看下面的例子:
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
:
Now, the following code throws an AttributeError
:
u = User(name="Max Mueller")
print u.comment
捕获该异常并提供默认值(如空字符串)的最佳方法是什么?
What would be the best way to catch that exception and provide a default value instead (like an empty string)?
推荐答案
你真的需要 association_proxy
来解决这个问题.使用常规的属性
,您真的可以过得很好.AttributeError
是(可能)引起的,因为 comment_object 本身是 None
,因为没有依赖行,并且 None
没有 comment
属性.
You don't really need association_proxy
for this. You could really get by just fine with a regular property
. The AttributeError
is (probably) caused because the comment_object is itself None
, since there is no dependent row, and None
has no comment
attribute.
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
这篇关于如何扩展SQLAlchemy 的association_proxy 的`getter` 功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!