以SQL Alchemy文档中的多对多association_proxy
为例,我尝试将其设置为双向工作。我的目标是设置模型,以便在删除关键字时,所有与用户的关联都将从关联表中清除。以下是我正在玩的代码:
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
keywords = association_proxy('user_keywords', 'keyword')
def __init__(self, name):
self.name = name
def __repr__(self):
return 'User(%s)' % repr(self.name)
class Keyword(Base):
__tablename__ = 'keyword'
id = Column(Integer, primary_key=True)
keyword = Column('keyword', String(64))
users = association_proxy('keyword_users', 'user')
def __init__(self, keyword):
self.keyword = keyword
def __repr__(self):
return 'Keyword(%s)' % repr(self.keyword)
class UserKeyword(Base):
__tablename__ = 'user_keyword'
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
keyword_id = Column(Integer, ForeignKey('keyword.id'), primary_key=True)
special_key = Column(String(50))
user = relationship(User,
backref=backref('user_keywords',
cascade='all, delete-orphan'))
keyword = relationship(Keyword,
backref=backref('keyword_users',
cascade ='all, delete-orphan'))
def __init__(self, keyword=None, user=None, special_key=None):
self.user = user
self.keyword = keyword
self.special_key = special_key
def __repr__(self):
return "UserKeyword({0}, {1}) Special: {2}".format(user.name,
keyword.keyword,
self.special_key)
测试它:
from sqlalchemy import create_engine
engine = create_engine('sqlite://')
from sqlalchemy.orm import sessionmaker
session = sessionmaker()
session.configure(bind=engine)
Base.metadata.create_all(engine)
s = session()
bob = User('Bob')
yay = Keyword('yay')
argh = Keyword('argh')
print("Everything: {0}, {1}, {2}".format(bob, yay, argh))
bob.keywords.append(yay)
print("{0} now has users {1}".format(yay, yay.users))
print("{0} now has users {1}".format(argh, argh.users))
argh.users.append(bob)
以下是我运行时看到的输出:
Players: User('Bob'), Keyword('yay'), Keyword('argh')
Keyword('yay') now has users [User('Bob')]
Keyword('argh') now has users []
Traceback (most recent call last):
File "assoc_proxy.py", line 78, in <module>
argh.users.append(bob)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/ext/associationproxy.py", line 595, in append
item = self._create(value)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/ext/associationproxy.py", line 522, in _create
return self.creator(value)
File "<string>", line 4, in __init__
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 196, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "assoc_proxy.py", line 50, in __init__
self.keyword = keyword
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 220, in __set__
instance_dict(instance), value, None)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 780, in set
value = self.fire_replace_event(state, dict_, value, old, initiator)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 801, in fire_replace_event
value = fn(state, value, previous, initiator or self._replace_token)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 1101, in emit_backref_from_scalar_set_event
child_impl = child_state.manager[key].impl
KeyError: 'keyword_users'
在orm/attributes.py
的第1101行放置一个断点我看到child_state.manager
交替携带keyword_users
密钥而不是association_proxy
密钥。每个关联表只允许{{1}}一次吗?
答案 0 :(得分:-1)
我相信它是因为您没有名为keyword_users的表格。它应该是&#34; user_keyword&#34;,这是您的关联表的名称。