Работающий функционал

This commit is contained in:
astakhovp committed 2026-10-10 20:41:32 +03:00
1 parent 3b1df81c41
commit 04138d36b1
14 files changed
+2879 -933

No files matched your search

+150
View File
@@ -0,0 +1,150 @@
#!/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