Sqlalchemy 如何插入';答案';模型

Sqlalchemy 如何插入';答案';模型,sqlalchemy,relationship,Sqlalchemy,Relationship,标题可能不太准确,但我不知道如何表达它 我有三门课:用户、问题、答案。简单的代码是: Session = scoped_session(sessionmaker()) Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) questions = relationship('Question', backref=

标题可能不太准确,但我不知道如何表达它

我有三门课:用户、问题、答案。简单的代码是:

Session = scoped_session(sessionmaker())
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)

    questions = relationship('Question', backref="user")
    answers = relationship('Answer', backref="user")

class Question(Base):
     __tablename__ = 'questions'
     id = Column(Integer, primary_key=True)
     user_id = Column(Integer, ForeignKey('users.id'))

     answers = relationship('Answer', backref="user")

class Answer(Base):
     __tablename__ = 'answers'
     user_id = Column(Integer, ForeignKey('users.id'))
     question_id = Column(Integer, ForeignKey('questions.id'))

     id = Column(Integer, primary_key=True)
现在,一个用户问了一个问题,因此将创建一个答案:

user = get_user_from_session()
question = get_question(question_id)

# create answer
answer = Answer()
answer.user = user
answer.question = question

Session.add(answer)  # !!!
Session.commit()
我希望将答案插入数据库,但不幸的是,报告了一个错误:

 AttributeError: 'module' object has no attribute '_sa_instance_state'
我错过了什么吗?如何修复它


更新

谢谢@dhaffey,我已经纠正了拼写错误。我重新创建了一个测试文件来测试这一点,发现没有再次发生错误,但
answer.user\u id
answer.question\u id
在提交后在数据库中为空

这是我的代码,你可以直接运行

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import *

engine = create_engine('sqlite:///test.sqlite', echo=True)
Session = scoped_session(sessionmaker())
Base = declarative_base()

Base.metadata.bind=engine

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    questions = relationship('Question')
    answers = relationship('Answer')

class Question(Base):
    __tablename__ = 'questions'
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('users.id'))
    title = Column(String)
    answers = relationship('Answer')

class Answer(Base):
    __tablename__ = 'answers'
    user_id = Column(Integer, ForeignKey('users.id'))
    question_id = Column(Integer, ForeignKey('questions.id'))

    id = Column(Integer, primary_key=True)

Base.metadata.create_all()

user = User()
user.name = 'aaa'
Session.add(user)
Session.flush()

question = Question()
question.title = 'ttt'
question.user = user
Session.add(question)
Session.flush()

answer = Answer()
answer.user = user
answer.question = question

Session.add(answer)
Session.commit()

print answer.id # not None

found = Session.query(Answer).filter_by(id=answer.id).one()

print found.user.name # not None
print found.question.title # not None

# !!! It seems all models are saved correctly,
# but please open the test.sqlite database, (not querying by sqlahchemy)
# the question.user_id and answer.user_id and answer.question_id are null

您的类声明没有为我“编译”,所以我想知道您是否运行过这段代码,如果是,您使用的是哪个SQLAlchemy版本。线路

user_id = Column(Integer, ForeignKey='users.id')
提高

sqlalchemy.exc.ArgumentError: Unknown arguments passed to Column: ['ForeignKey']
使用SQLAlchemy 0.6.4。您试图用关键字参数声明外键,但正确的用法是构造一个
ForeignKey
对象并按位置传递它,如下所示:

user_id = Column(Integer, ForeignKey('users.id'))
在外键已修复的情况下,您的示例对我来说就像预期的那样有效


请注意,当相应的外键被正确声明时,您不需要显式地在这些关系上提供
primaryjoin
参数-SQLAlchemy推断正确的连接。

对不起,
ForeignKey
错误是一个打字错误(我手工编写代码,不是复制的)。我刚刚修复了它并再次尝试,发现这次没有发生错误(可能示例代码比实际代码容易得多),但是
答案。用户id
答案。问题id
在数据库中为空。所以,
answer.user=user
answer.question=question
实际上什么都不做。您能再次运行测试并检查此问题吗?当您修复其他打字错误时,您通过删除某些关系的
backref
参数引入了一个新错误。没有这些属性,
user
question
属性只是常规的Python属性,没有数据库支持。使用即时查询返回它们的原因是SQLAlchemy从其标识映射返回相同的实例(具有相同的瞬态Python状态)。为
user.questions
user.answers
指定
backref='user'
,为
question.answers指定
backref='question'
,将它们转换回数据库支持的属性。非常抱歉,这是一个新的输入错误。更新后的代码就是我测试时使用的代码。也有同样的错误:数据库中的数据没有
user\u id
question\u id
现在看起来您已经用
backref
参数更新了代码的原始版本,但我认为您可能仍然在测试问题中没有参数的代码。如果我使用第一组类定义,行
user=user()
会引发异常,因为您为
Question.answers粘贴了
backref=“user”
,而不是
backref=“Question”
。如果我修复了这个问题并运行了您的测试,那么所有内容都会像预期的那样出现在数据库中。