我有一个模拟Users
,Questions
和Answers
的数据库。
Questions
具有特定的type
和value
,作为应用程序的一部分,我需要知道每种问题类型的User
总数。
当前,我正在使用python
执行此求和,但是我想要一个更好,更有效的解决方案,该解决方案使用基础数据库和适当的功能(func.sum
等)。
对数据库和当前解决方案的描述如下:
import datetime
from sqlalchemy import create_engine, Column, ForeignKey, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
from itertools import groupby
Base = declarative_base()
class Answer(Base):
__tablename__ = 'answer'
question_id = Column(Integer, ForeignKey('question.id'), primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
question_answers = relationship('Question', back_populates='answers')
user_answers = relationship('User', back_populates='answers')
time_answered = Column(DateTime, default=datetime.datetime.utcnow, nullable=False)
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True, autoincrement=True)
answers = relationship(Answer, back_populates='user_answers', order_by='Answer.time_answered.desc()', lazy='dynamic')
@property
def get_answer_totals(self):
answer_totals = dict()
sorted_answers = sorted(self.answers, key=lambda x: x.question_answers.type)
for k, v in groupby(sorted_answers, lambda x: x.question_answers.type):
answer_totals[k] = sum([answer.question_answers.value for answer in list(v)])
return answer_totals
class Question(Base):
__tablename__ = 'question'
id = Column(Integer, primary_key=True, autoincrement=True)
type = Column(Integer, nullable=False)
value = Column(Integer, nullable=False)
answers = relationship(Answer, back_populates='question_answers', order_by='Answer.time_answered.desc()', lazy='dynamic')
engine = create_engine('sqlite:///soq.db')
DBSession = sessionmaker(bind=engine)
session = DBSession()
Base.metadata.create_all(engine)
user_1 = User(id=1)
user_2 = User(id=2)
session.add_all([user_1, user_2])
question_1 = Question(id=1,type="A",value=50)
question_2 = Question(id=2,type="A",value=10)
question_3 = Question(id=3,type="B",value=20)
question_4 = Question(id=4,type="B",value=30)
question_5 = Question(id=5,type="C",value=10)
session.add_all([question_1, question_2, question_3, question_4, question_5])
user_1.answers.append(Answer(question_id=1,user_id=1))
user_1.answers.append(Answer(question_id=3,user_id=1))
user_1.answers.append(Answer(question_id=4,user_id=1))
print user_1.get_answer_totals
user_2.answers.append(Answer(question_id=1,user_id=2))
user_2.answers.append(Answer(question_id=2,user_id=2))
user_2.answers.append(Answer(question_id=5,user_id=2))
print user_2.get_answer_totals
从上面可以看出,get_answer_totals
类中的(丑陋的)User
函数首先对数据进行排序,然后对其进行分组,然后对其进行计数。
有人可以帮助我将此功能转换为等效的SQLAlchemy
查询吗?
答案 0 :(得分:0)
针对其他有相同问题的人的解决方案,
@property
def get_answer_totals2(self):
return self.answers.join(Question, Question.id == Answer.question_id).add_column(Question.type).add_column(func.sum(Question.value)).group_by(Question.type).all()