When attempting to add a Widget
to the (SQLite) DB, and associate it with an already existing User
as defined below:
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>)]
I can add the value for user.name
directly, but this breaks the relationship. For example, widget.user.name
would give an error like 'str' object has no attribute 'repository'
The backref
attribute will do what you need. 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:
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. You can not assign a User object to an attribute which expects to be a string.
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.
You need to set up a relationship between your two ORM classes:
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.