urs*_*rei 10 python sqlalchemy
我有两张桌子,tablet
并且correspondent
:
class Correspondent(db.Model, GlyphMixin):
# PK column and tablename etc. come from the mixin
name = db.Column(db.String(100), nullable=False, unique=True)
# association proxy
tablets = association_proxy('correspondent_tablets', 'tablet')
def __init__(self, name, tablets=None):
self.name = name
if tablets:
self.tablets = tablets
class Tablet(db.Model, GlyphMixin):
# PK column and tablename etc. come from the mixin
area = db.Column(db.String(100), nullable=False, unique=True)
# association proxy
correspondents = association_proxy('tablet_correspondents', 'correspondent')
def __init__(self, area, correspondents=None):
self.area = area
if correspondents:
self.correspondents = correspondents
class Tablet_Correspondent(db.Model):
__tablename__ = "tablet_correspondent"
tablet_id = db.Column("tablet_id",
db.Integer(), db.ForeignKey("tablet.id"), primary_key=True)
correspondent_id = db.Column("correspondent_id",
db.Integer(), db.ForeignKey("correspondent.id"), primary_key=True)
# relations
tablet = db.relationship(
"Tablet",
backref="tablet_correspondents",
cascade="all, delete-orphan",
single_parent=True)
correspondent = db.relationship(
"Correspondent",
backref="correspondent_tablets",
cascade="all, delete-orphan",
single_parent=True)
def __init__(self, tablet=None, correspondent=None):
self.tablet = tablet
self.correspondent = correspondent
Run Code Online (Sandbox Code Playgroud)
我可以将记录添加到tablet
和correspondent
,并且例如Tablet.query.first().correspondents
只是返回一个空列表,正如您所期望的那样.如果我tablet_correspondent
使用现有的平板电脑和对应的ID 手动在我的表中插入一行,则会再次按照您的预期填充列表.
但是,如果我尝试做的话
cor = Correspondent.query.first()
tab = Tablet.query.first()
tab.correspondents.append(cor)
Run Code Online (Sandbox Code Playgroud)
我明白了:
KeyError: 'tablet_correspondents'
Run Code Online (Sandbox Code Playgroud)
我很确定我在这里遗漏了一些相当基本的东西.
van*_*van 12
代码的问题在于.__init__
方法.如果你是debug-watch/print()
参数,你会注意到参数tablet
实际上是一个实例Correspondent
:
class Tablet_Correspondent(db.Model):
def __init__(self, tablet=None, correspondent=None):
print "in __init__: ", tablet, correspondent
self.tablet = tablet
self.correspondent = correspondent
Run Code Online (Sandbox Code Playgroud)
这样做的原因是SA创建新值的方式.从文档创建新值:
当关联代理拦截列表
append()
事件(或集合add()
,字典__setitem__()
或标量赋值事件)时,它使用其构造函数实例化"中间"对象的新实例,将给定值作为单个参数传递.
在您调用的情况下tab.correspondents.append(cor)
,Tablet_Correspondent.__init__
使用单个参数调用cor
.
解?如果你只会被添加Correspondents
到Tablet
,然后就切换的参数__init__
.实际上,完全删除第二个参数.
但是,如果您也将使用cor.tablets.append(tab)
,那么您需要明确地使用与上面链接的文档中所解释的creator
参数association_proxy
:
class Tablet(db.Model, GlyphMixin):
# ...
correspondents = association_proxy('tablet_correspondents', 'correspondent', creator=lambda cor: Tablet_Correspondent(correspondent=cor))
class Correspondent(db.Model, GlyphMixin):
# ...
tablets = association_proxy('correspondent_tablets', 'tablet', creator=lambda tab: Tablet_Correspondent(tablet=tab))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5829 次 |
最近记录: |