[英]Associating an SQLAlchemy object with an existing record (Python/Pyramid)
When attempting to add a Widget
to the (SQLite) DB, and associate it with an already existing User
as defined below: 尝试将Widget
添加到(SQLite)数据库时,将其与已存在的User
关联,如下所示:
class Widget(Base):
__tablename__ = 'widgets'
id = Column(Integer, primary_key=True)
kind = Column(Text)
user = Column(Text, ForeignKey('users.name'))
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(Text, unique=True)
@view_config(route_name='name', renderer='json')
def add_widget(request):
user_name = 'foo'
user = request.dbsession.query(User).filter_by(name=user_name).one()
new_widget = Widget(kind='bar', user=user)
I receive the error sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 1 - probably unsupported type. [SQL: 'INSERT INTO widgets (kind, user) VALUES (?, ?)'] [parameters: ('bar', <example.models.user.User object at 0x1050bdghd>)]
我收到错误sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 1 - probably unsupported type. [SQL: 'INSERT INTO widgets (kind, user) VALUES (?, ?)'] [parameters: ('bar', <example.models.user.User object at 0x1050bdghd>)]
sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 1 - probably unsupported type. [SQL: 'INSERT INTO widgets (kind, user) VALUES (?, ?)'] [parameters: ('bar', <example.models.user.User object at 0x1050bdghd>)]
I can add the value for user.name
directly, but this breaks the relationship. 我可以直接为user.name
添加值,但这会破坏关系。 For example, widget.user.name
would give an error like 'str' object has no attribute 'repository'
例如, widget.user.name
会给出类似'str' object has no attribute 'repository'
The backref
attribute will do what you need. backref
属性将满足您的需求。 Add a relationship to user class as follows: 向用户类添加关系,如下所示:
class User(Base):
...
widget = sqlalchemy.orm.relationship('Widget', backref='user')
With backref attribute sqlalchemy will add a reference to your Widget class which will point User object: 使用backref属性,sqlalchemy将添加对Widget类的引用,该类将指向User对象:
user = request.dbsession.query(User).filter_by(name=user_name).one()
new_widget = Widget(kind='bar', user=user)
Your Widget
class has a user
attribute which is of type Text
, which is basically a string attribute on the Python side of things and is something like VARCHAR column in the database. 您的Widget
类具有一个Text
类型的user
属性,它基本上是Python方面的字符串属性,类似于数据库中的VARCHAR列。 You can not assign a User object to an attribute which expects to be a string. 您不能将User对象分配给期望为字符串的属性。
It also appears that you're trying to create a foreign key relationship using the users.name
column - this is certainly possible but is quite unusual considering you also have a surrogate primary key on your User
model. 您似乎也尝试使用users.name
列创建外键关系 - 这当然是可能的,但考虑到您的User
模型上还有一个代理主键,这是非常不寻常的。
You need to set up a relationship between your two ORM classes: 您需要在两个ORM类之间建立关系 :
class Widget(Base):
__tablename__ = 'widgets'
id = Column(Integer, primary_key=True)
kind = Column(Text)
user_id = Column(Integer, ForeignKey('users.id'))
user = sqlalchemy.orm.relationship('User', backref='widgets')
then you'll be able to do any of the following: 然后你就可以做以下任何事情:
new_widget = Widget(kind='bar', user=user)
new_widget = Widget(kind='bar', user_id=user.id)
user.widgets.append(Widget(kind='bar'))
new_widget.user_id = user.id
new_widget.user = user
You can also set up things from the other end as @metmirr suggested, but the magic ingredient here is sqlalchemy.orm.relationship , not the backref which you may or may not choose to have. 您也可以从另一端设置事情@metmirr建议,但这里的神奇成分是sqlalchemy.orm.relationship ,而不是backref您可能会或可能不会选择有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.