Reputation: 566
I have a table called article
. It has a column article.id
and article.snippet
.
I have another table called article_vote
. It has a column article_id
(which is a foreign key for article.id
) and vote_choice_id
(which is a number from 1 to 6).
I want to plug a snippet in and have the program count all the vote_choice_id
’s for that snippet when the vote_choice_id = 1, vote_choice_id = 2, vote_choice_id = 3, etc. That means cross-referencing these two tables, which confuses me.
Here's my current code:
##############################################
class Article(db.Model):
# object mirrors table 'article'
id = db.Column('id', db.Integer, primary_key=True)
title = db.Column(db.String(400))
url = db.Column(db.String(400))
image_url = db.Column(db.String(400))
snippet = db.Column(db.String(1000))
date_upload = db.Column(db.DateTime(), default=datetime.utcnow)
def __init__(self, title, url, image_url, snippet):
self.title = title
self.url = url
self.image_url = image_url
self.snippet = snippet
##############################################
class ArticleVote(db.Model):
# object mirrors table 'article_vote'
id = db.Column('id', db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.fb_id')) # Sloppy
article_id = db.Column(db.Integer, db.ForeignKey('article.id'))
vote_choice_id = db.Column(db.Integer)
comment = db.Column(db.String(400))
def __init__(self, user_id, article_id, vote_choice_id, comment):
self.user_id = user_id
self.article_id = article_id
self.vote_choice_id = vote_choice_id
self.comment = comment
And then here's what I wrote after I tried to follow an example that I couldn't quite understand:
##############################################
class PublicationVoteSummary():
# This object keeps the count of votes for a Publication
def __init__(self, article_id):
self.snippet = snippet
self.choice_count = {} # count by textual choice
self.choice_id = {}
pub_choice_list = VoteChoice.getVoteChoiceList()
for item in pub_choice_list:
self.choice_id[str(item.id)] = item.choice
for item in pub_choice_list:
self.choice_count[item.choice] = 0
self.total_votes = 0
def addVote(self, choice):
self.choice_count[choice] = self.choice_count[choice] + 1
self.total_votes = self.total_votes + 1
def getVoteCount(self, choice):
return self.choice_count[choice]
##############################################
def retrieve_publication_summary(article_id):
pub_obj = PublicationSummary(article_id)
publication_list = db.session.query(ArticleVote, Snippet).filter(ArticleVote.article_id == article_id).filter(
ArticleVote.vote_choice_id == 1).all()
for item in vote_choice_id:
# avs_obj.appendComment(item.comment) # 09/27 - added to show comments in results page
avs_obj.appendDetail((item[1].name, text, item[0].comment))
return pub_obj
I also tried this:
SELECT 1.(count)
FROM article_vote
INNER JOIN vote_choice_id
ON Article.id = Article_vote.article_id
WHERE Article_vote.vote_choice_id = 1
Upvotes: 0
Views: 590
Reputation: 55600
This query will output the snippet
and count of votes for each vote_choice_id
for that snippet (as long as there at least one vote_choice_id
for a given snippet).
import sqlalchemy as sa
q = (db.session.query(Article.snippet, ArticleVote.vote_choice_id, sa.func.count(ArticleVote.id))
.join(ArticleVote, Article.id == ArticleVote.article_id)
.group_by(Article.snippet, ArticleVote.vote_choice_id)
.order_by(Article.snippet, ArticleVote.vote_choice_id.desc()))
for snippet, vote_choice_id, count in q:
print(snippet, vote_choice_id, count)
The code generates this SQL:
SELECT article.snippet AS article_snippet, article_vote.vote_choice_id AS article_vote_vote_choice_id, count(article_vote.id) AS count_1
FROM article
JOIN article_vote ON article.id = article_vote.article_id
GROUP BY article.snippet, article_vote.vote_choice_id
ORDER BY article.snippet, article_vote.vote_choice_id DESC
And produces output like
New York Times 6 38
New York Times 5 46
New York Times 4 36
New York Times 3 44
New York Times 2 34
...
To get the count for a given snippet
and vote_choice_id
can be obtained by adding filters to the query (and removing vote_choice_id
from the output, and the GROUP BY
and ORDER BY
clauses):
q = (db.session.query(Article.snippet, sa.func.count(ArticleVote.id))
.join(ArticleVote, Article.id == ArticleVote.article_id)
.filter(Article.snippet == 'New York Times')
.filter(ArticleVote.vote_choice_id == 2)
.group_by(Article.snippet))
for snippet, count in q:
print(snippet, count)
Generating this SQL:
SELECT article.snippet AS article_snippet, count(article_vote.id) AS count_1
FROM article
JOIN article_vote ON article.id = article_vote.article_id
WHERE article.snippet = ? AND article_vote.vote_choice_id = ?
and this output:
New York Times 34
Upvotes: 1