2026-09-01 22:35:05 +01:00
|
|
|
import os
|
2026-09-01 22:45:55 +01:00
|
|
|
import pandas as pd
|
2026-09-01 22:35:05 +01:00
|
|
|
from dotenv import load_dotenv, find_dotenv
|
2026-09-01 22:45:55 +01:00
|
|
|
from sqlalchemy.engine import URL, create_engine
|
2026-09-01 22:51:06 +01:00
|
|
|
from sqlalchemy.engine.base import Engine
|
2026-09-01 22:45:55 +01:00
|
|
|
|
|
|
|
|
|
2026-09-01 22:51:06 +01:00
|
|
|
def get_engine() -> Engine:
|
|
|
|
|
"""Load env vars and return a SQLAlchemy engine connected to the database."""
|
|
|
|
|
load_dotenv(find_dotenv())
|
2026-09-01 22:45:55 +01:00
|
|
|
|
2026-09-01 22:51:06 +01:00
|
|
|
url = URL.create(
|
|
|
|
|
drivername="postgresql+psycopg2",
|
|
|
|
|
username=os.getenv("DATABASE_USERNAME"),
|
|
|
|
|
password=os.getenv("DATABASE_PASSWORD"),
|
|
|
|
|
host=os.getenv("DATABASE_IP"),
|
|
|
|
|
port=int(os.getenv("DATABASE_PORT", 5432)),
|
|
|
|
|
database=os.getenv("DATABASE_NAME"),
|
|
|
|
|
)
|
2026-09-01 22:45:55 +01:00
|
|
|
|
2026-09-01 22:51:06 +01:00
|
|
|
return create_engine(url)
|
2026-09-01 22:45:55 +01:00
|
|
|
|
2026-09-01 22:51:06 +01:00
|
|
|
def run_query(engine: Engine, query: str) -> pd.DataFrame:
|
|
|
|
|
return pd.read_sql_query(query, engine)
|
2026-08-31 23:16:53 +01:00
|
|
|
|
2026-09-01 22:51:06 +01:00
|
|
|
def fetch_titles_and_genres(engine: Engine) -> pd.DataFrame:
|
|
|
|
|
"""Query title/genres from audiobookshelf.ao3 and return as a DataFrame."""
|
|
|
|
|
query = """SELECT title, genres FROM audiobookshelf.ao3;"""
|
|
|
|
|
return run_query(engine, query)
|
|
|
|
|
|
2026-09-01 23:01:33 +01:00
|
|
|
def count_genre_occurrences(data: pd.DataFrame, column: str = "genres") -> pd.Series:
|
|
|
|
|
"""Count how many times each genre appears across all titles."""
|
|
|
|
|
return data.explode(column)[column].value_counts()
|
|
|
|
|
|
2026-09-01 22:51:06 +01:00
|
|
|
def main():
|
|
|
|
|
engine = get_engine()
|
|
|
|
|
data = fetch_titles_and_genres(engine)
|
2026-09-01 23:01:33 +01:00
|
|
|
genre_counts = count_genre_occurrences(data)
|
|
|
|
|
print(genre_counts)
|
|
|
|
|
# print(data.head())
|
2026-09-01 22:51:06 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|