Как вставить модель «ответ»? - PullRequest
1 голос
/ 08 сентября 2010

Название может быть не совсем, но я не знаю, как это выразить.

У меня есть 3 класса: пользователь, вопрос, ответ.Простой код:

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_id и answer.question_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

1 Ответ

2 голосов
/ 08 сентября 2010

Ваши объявления классов не "компилируются" для меня, поэтому мне интересно, запускали ли вы этот код, и какую версию 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 выводит правильное соединение.

...