Перекрестные ссылки на две таблицы в python? - PullRequest
0 голосов
/ 04 мая 2020

У меня есть таблица с именем article. В нем есть столбец article.id и article.snippet.

У меня есть еще одна таблица с именем article_vote. У него есть столбец article_id (который является внешним ключом для article.id) и vote_choice_id (который является числом от 1 до 6).

Я хочу подключить фрагмент и получить программу подсчитать все vote_choice_id для этого фрагмента, когда voice_choice_id = 1, voice_choice_id = 2, voice_choice_id = 3 и т. д. c. Это означает перекрестную ссылку на эти две таблицы, что меня смущает.

Вот мой текущий код:

##############################################
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

И вот что я написал после того, как попытался следовать примеру, который я не совсем понял:

##############################################
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

Я также попробовал это:

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

1 Ответ

1 голос
/ 04 мая 2020

Этот запрос выведет snippet и количество голосов для каждого vote_choice_id для этого фрагмента (если существует хотя бы один vote_choice_id для данного фрагмента).

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)

код генерирует это 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

и производит вывод наподобие

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
...

Чтобы получить счет для заданных snippet и vote_choice_id, можно получить, добавив фильтры в запрос (и удаление vote_choice_id из вывода и предложений GROUP BY и ORDER BY):

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)

Генерация этого 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 = ? 

и этого вывод:

New York Times 34
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...