将SQLAlchemy对象与现有记录关联(Python/Pyramid)

将SQLAlchemy对象与现有记录关联(Python/Pyramid),python,sqlite,sqlalchemy,pyramid,Python,Sqlite,Sqlalchemy,Pyramid,尝试将小部件添加到(SQLite)DB中,并将其与已存在的用户关联时,定义如下: class Widget(Base): __tablename__ = 'widgets' id = Column(Integer, primary_key=True) kind = Column(Text) user = Column(Text, ForeignKey('users.name')) class User(Base): __tablename__ = 'us

尝试将
小部件
添加到(SQLite)DB中,并将其与已存在的
用户关联时,定义如下:

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)
我收到错误
sqlalchemy.exc.interfaceeerror:(sqlite3.interfaceeerror)错误绑定参数1-可能是不支持的类型。[SQL:'插入小部件(种类、用户)值(?,)'][参数:('bar',)]


我可以直接为
user.name
添加值,但这会破坏关系。例如,
widget.user.name
将给出一个错误,如
'str'对象没有属性“repository”
属性
backref
将执行您需要的操作。将关系添加到用户类,如下所示:

class User(Base):
    ...
    widget = sqlalchemy.orm.relationship('Widget', backref='user')
使用backref属性,sqlalchemy将添加对小部件类的引用,该类将指向用户对象:

user = request.dbsession.query(User).filter_by(name=user_name).one()
new_widget = Widget(kind='bar', user=user)

backref
属性将执行您需要的操作。将关系添加到用户类,如下所示:

class User(Base):
    ...
    widget = sqlalchemy.orm.relationship('Widget', backref='user')
使用backref属性,sqlalchemy将添加对小部件类的引用,该类将指向用户对象:

user = request.dbsession.query(User).filter_by(name=user_name).one()
new_widget = Widget(kind='bar', user=user)

您的
Widget
类有一个
user
属性,该属性的类型为
Text
,它基本上是Python端的字符串属性,类似于数据库中的VARCHAR列。不能将用户对象指定给预期为字符串的属性

您似乎还试图使用
users.name
列创建外键关系-这当然是可能的,但考虑到您的
User
模型上还有一个代理主键,这是非常不寻常的

您需要在两个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')
然后您将能够执行以下任一操作:

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

您也可以按照@metmirr的建议从另一端设置东西,但这里的神奇成分不是您可以选择或不选择的。

您的
Widget
类有一个
user
属性,该属性的类型为
Text
,它基本上是Python方面的字符串属性,类似于数据库中的VARCHAR列。不能将用户对象指定给预期为字符串的属性

您似乎还试图使用
users.name
列创建外键关系-这当然是可能的,但考虑到您的
User
模型上还有一个代理主键,这是非常不寻常的

您需要在两个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')
然后您将能够执行以下任一操作:

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
你也可以像@metmirr建议的那样从另一端设置东西,但这里的神奇成分不是你可以选择或不选择的