Files

150 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Модуль для работы с авторами"""
from db_utils import get_cursor
def get_authors_by_prefix(prefix=''):
"""Возвращает авторов по префиксу фамилии"""
conn, cur = get_cursor()
if prefix:
cur.execute("""
SELECT a.id, a.full_name, a.name_hash,
COUNT(DISTINCT ba.book_id) as books_count
FROM authors a
LEFT JOIN book_authors ba ON ba.author_id = a.id
WHERE a.last_name ILIKE %s
GROUP BY a.id, a.full_name, a.name_hash
ORDER BY a.last_name, a.first_name
LIMIT 100
""", (prefix + '%',))
else:
cur.execute("""
SELECT DISTINCT lower(substring(last_name, 1, 1)) as letter,
COUNT(*) as cnt
FROM authors
WHERE last_name ~ '^[а-яА-Яa-zA-Z]'
GROUP BY lower(substring(last_name, 1, 1))
ORDER BY letter
""")
result = cur.fetchall()
conn.close()
return result
def get_author_prefixes(prefix=''):
"""Возвращает группировку по следующим буквам"""
conn, cur = get_cursor()
next_len = len(prefix) + 1
cur.execute("""
SELECT DISTINCT
substring(last_name, %s, 1) as next_letter,
COUNT(*) as cnt,
MIN(last_name) as first_author,
MAX(last_name) as last_author
FROM authors
WHERE last_name ILIKE %s
GROUP BY substring(last_name, %s, 1)
ORDER BY next_letter
""", (next_len, prefix + '%', next_len))
result = cur.fetchall()
conn.close()
return result
def get_author_by_hash(author_hash):
"""Возвращает автора по хешу"""
conn, cur = get_cursor()
cur.execute("""
SELECT id, full_name, last_name, first_name, middle_name, name_hash
FROM authors
WHERE name_hash = %s
""", (author_hash,))
author = cur.fetchone()
conn.close()
return author
def get_author_series(author_id):
"""Возвращает серии автора"""
conn, cur = get_cursor()
cur.execute("""
SELECT DISTINCT s.id, s.name, s.name_hash,
COUNT(DISTINCT b.id) as books_count
FROM series s
JOIN books b ON b.series_id = s.id
JOIN book_authors ba ON ba.book_id = b.id
WHERE ba.author_id = %s
GROUP BY s.id, s.name, s.name_hash
ORDER BY s.name
""", (author_id,))
series = cur.fetchall()
conn.close()
return series
def get_author_books(author_id):
"""Возвращает книги автора (без серий)"""
conn, cur = get_cursor()
# Простой запрос без string_agg
cur.execute("""
SELECT b.id, b.title, b.language, b.added_date, b.series_number,
s.name as series_name, s.name_hash as series_hash
FROM books b
JOIN book_authors ba ON ba.book_id = b.id
LEFT JOIN series s ON s.id = b.series_id
WHERE ba.author_id = %s
GROUP BY b.id, b.title, b.language, b.added_date, b.series_number,
s.name, s.name_hash
ORDER BY b.added_date DESC NULLS LAST
""", (author_id,))
books = cur.fetchall()
# Для каждой книги получаем количество авторов и соавторов
for book in books:
cur.execute("""
SELECT COUNT(*) as cnt
FROM book_authors
WHERE book_id = %s
""", (book['id'],))
book['authors_count'] = cur.fetchone()['cnt']
cur.execute("""
SELECT string_agg(a.full_name, ', ' ORDER BY ba.position) as coauthors
FROM book_authors ba
JOIN authors a ON a.id = ba.author_id
WHERE ba.book_id = %s
""", (book['id'],))
book['coauthors'] = cur.fetchone()['coauthors']
conn.close()
return books
def get_series_books(series_id):
"""Возвращает все книги серии"""
conn, cur = get_cursor()
cur.execute("""
SELECT b.id, b.title, b.language, b.series_number,
string_agg(DISTINCT a.full_name, ', ' ORDER BY ba.position) as authors
FROM books b
JOIN book_authors ba ON ba.book_id = b.id
JOIN authors a ON a.id = ba.author_id
WHERE b.series_id = %s
GROUP BY b.id, b.title, b.language, b.series_number
ORDER BY b.series_number
""", (series_id,))
books = cur.fetchall()
conn.close()
return books