Python SQL炼金术协会代理不';我不能两全其美
遵循SQL Alchemy文档中的多对多示例,我尝试使其同时工作。我的目标是建立模型,这样当我删除关键字时,它与用户的所有关联都将从关联表中清除。下面是我正在使用的代码:Python SQL炼金术协会代理不';我不能两全其美,python,sqlalchemy,many-to-many,bidirectional,Python,Sqlalchemy,Many To Many,Bidirectional,遵循SQL Alchemy文档中的多对多示例,我尝试使其同时工作。我的目标是建立模型,这样当我删除关键字时,它与用户的所有关联都将从关联表中清除。下面是我正在使用的代码: from sqlalchemy import Column, Integer, String, ForeignKey from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.associationproxy import association
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'
Players:User('Bob')、关键字('yay')、关键字('argh'))
关键字('yay')现在有用户[用户('Bob')]
关键字('argh')现在有用户[]
回溯(最近一次呼叫最后一次):
文件“assoc_proxy.py”,第78行,在
argh.users.append(bob)
文件“/usr/local/lib/python2.7/site packages/sqlalchemy/ext/associationproxy.py”,第595行,在附录中
项目=自我创造(价值)
文件“/usr/local/lib/python2.7/site packages/sqlalchemy/ext/associationproxy.py”,第522行,在创建
返回self.creator(值)
文件“”,第4行,在_init中__
文件“/usr/local/lib/python2.7/site packages/sqlalchemy/orm/state.py”,第196行,在初始化实例中
退货经理。原始初始(*混合[1:],**kwargs)
文件“assoc_proxy.py”,第50行,在_init中__
self.keyword=关键字
文件“/usr/local/lib/python2.7/site packages/sqlalchemy/orm/attributes.py”,第220行,在__
实例(实例,值,无)
文件“/usr/local/lib/python2.7/site packages/sqlalchemy/orm/attributes.py”,第780行,在集合中
value=self.fire\u replace\u事件(状态、dict\u、值、旧、启动器)
fire\u replace\u事件中的文件“/usr/local/lib/python2.7/site packages/sqlalchemy/orm/attributes.py”,第801行
value=fn(状态、值、先前、启动器或自身。\u替换\u令牌)
文件“/usr/local/lib/python2.7/site packages/sqlalchemy/orm/attributes.py”,第1101行,在emit\u backref\u from\u scalar\u set\u事件中
child\u impl=child\u state.manager[key].impl
KeyError:'关键字\用户'
在
orm/attributes.py
的第1101行放置一个断点,我看到child\u state.manager
交替地携带关键字用户
键,而不携带。每个关联表只允许一次关联\u代理吗?我相信这是因为您没有一个名为keyword\u users的表。它应该是“user_关键字”,这是关联表的名称