Automated Action 9623558845 Add character management system
- Enhance character model with additional fields
- Create relationship between anime and characters
- Implement character search functionality
- Create Alembic migration for character table
- Add sample character data for seeding
- Update README with character endpoint information
2025-05-17 22:02:13 +00:00

227 lines
9.0 KiB
Python

import logging
from datetime import date
from sqlalchemy.orm import Session
from app import crud, schemas
from app.db.session import SessionLocal
logger = logging.getLogger(__name__)
# Example genres
INITIAL_GENRES = [
{"name": "Action"},
{"name": "Adventure"},
{"name": "Comedy"},
{"name": "Drama"},
{"name": "Fantasy"},
{"name": "Horror"},
{"name": "Mystery"},
{"name": "Romance"},
{"name": "Sci-Fi"},
{"name": "Slice of Life"},
{"name": "Sports"},
{"name": "Supernatural"},
{"name": "Thriller"},
]
# Example anime
INITIAL_ANIME = [
{
"title": "Fullmetal Alchemist: Brotherhood",
"alternative_titles": "Hagane no Renkinjutsushi: Fullmetal Alchemist",
"synopsis": "After a horrific alchemy experiment goes wrong in the Elric household, brothers Edward and Alphonse are left in a catastrophic new reality.",
"episodes": 64,
"status": "Finished Airing",
"aired_from": date(2009, 4, 5),
"aired_to": date(2010, 7, 4),
"duration": "24 min per ep",
"rating": "R - 17+ (violence & profanity)",
"score": 9.15,
"ranked": 1,
"popularity": 3,
"studio": "Bones",
"source": "Manga",
"genre_ids": [1, 2, 4, 5], # Action, Adventure, Drama, Fantasy
},
{
"title": "Death Note",
"synopsis": "A high school student discovers a supernatural notebook that has deadly powers. When he discovers that he can kill anyone by writing their name in the notebook, he begins to create his perfect world.",
"episodes": 37,
"status": "Finished Airing",
"aired_from": date(2006, 10, 4),
"aired_to": date(2007, 6, 27),
"duration": "23 min per ep",
"rating": "R - 17+ (violence & profanity)",
"score": 8.63,
"ranked": 69,
"popularity": 1,
"studio": "Madhouse",
"source": "Manga",
"genre_ids": [7, 9, 13], # Mystery, Sci-Fi, Thriller
},
{
"title": "Attack on Titan",
"alternative_titles": "Shingeki no Kyojin",
"synopsis": "Centuries ago, mankind was slaughtered to near extinction by monstrous humanoid creatures called Titans, forcing humans to hide in fear behind enormous concentric walls.",
"episodes": 75,
"status": "Finished Airing",
"aired_from": date(2013, 4, 7),
"aired_to": date(2021, 3, 29),
"duration": "24 min per ep",
"rating": "R - 17+ (violence & profanity)",
"score": 8.51,
"ranked": 108,
"popularity": 2,
"studio": "Wit Studio",
"source": "Manga",
"genre_ids": [1, 4, 5], # Action, Drama, Fantasy
},
]
# Example characters
INITIAL_CHARACTERS = [
# Fullmetal Alchemist: Brotherhood characters
{
"name": "Edward Elric",
"role": "Main",
"description": "The primary protagonist of the series, Edward is a young alchemical prodigy who lost his right arm and left leg after a failed attempt to resurrect his mother. He is the youngest State Alchemist in history, joining the military at the age of 12.",
"voice_actor": "Romi Park (Japanese), Vic Mignogna (English)",
"image_url": "https://example.com/edward_elric.jpg",
"anime_title": "Fullmetal Alchemist: Brotherhood",
"age": "15-16",
"gender": "Male",
"birth_date": date(1899, 2, 3),
"height": "165 cm (5'5\")",
"weight": "55 kg (121 lbs)",
"blood_type": "O",
"popularity_rank": 1
},
{
"name": "Alphonse Elric",
"role": "Main",
"description": "Edward's younger brother, Alphonse lost his entire body in the failed human transmutation experiment. His soul was bound to a suit of armor by Edward, and he seeks to restore his original body.",
"voice_actor": "Rie Kugimiya (Japanese), Maxey Whitehead (English)",
"image_url": "https://example.com/alphonse_elric.jpg",
"anime_title": "Fullmetal Alchemist: Brotherhood",
"age": "14-15",
"gender": "Male",
"birth_date": date(1900, 5, 7),
"height": "250 cm (in armor)",
"blood_type": "B",
"popularity_rank": 2
},
# Death Note characters
{
"name": "Light Yagami",
"role": "Main",
"description": "The main protagonist of Death Note, Light is a high school student who discovers the Death Note. Disgusted with the crime and injustice in the world, he uses the Death Note's power to kill criminals and becomes known as 'Kira'.",
"voice_actor": "Mamoru Miyano (Japanese), Brad Swaile (English)",
"image_url": "https://example.com/light_yagami.jpg",
"anime_title": "Death Note",
"age": "17-23",
"gender": "Male",
"birth_date": date(1986, 2, 28),
"height": "179 cm (5'10\")",
"weight": "64 kg (141 lbs)",
"blood_type": "A",
"popularity_rank": 3
},
{
"name": "L Lawliet",
"role": "Main",
"description": "A mysterious detective with an eccentric personality who takes on the challenge of capturing Kira. Considered the world's greatest detective, L opposes Light in a psychological battle of wits.",
"voice_actor": "Kappei Yamaguchi (Japanese), Alessandro Juliani (English)",
"image_url": "https://example.com/l_lawliet.jpg",
"anime_title": "Death Note",
"age": "24-25",
"gender": "Male",
"birth_date": date(1979, 10, 31),
"height": "179 cm (5'10\")",
"weight": "50 kg (110 lbs)",
"blood_type": "Unknown",
"popularity_rank": 4
},
# Attack on Titan characters
{
"name": "Eren Yeager",
"role": "Main",
"description": "The main protagonist of Attack on Titan. After his mother is eaten by a Titan, Eren vows to exterminate all Titans. Later, he discovers he has the ability to transform into a Titan.",
"voice_actor": "Yuki Kaji (Japanese), Bryce Papenbrook (English)",
"image_url": "https://example.com/eren_yeager.jpg",
"anime_title": "Attack on Titan",
"age": "15-19",
"gender": "Male",
"birth_date": date(835, 3, 30),
"height": "170 cm (5'7\")",
"weight": "63 kg (139 lbs)",
"blood_type": "Unknown",
"popularity_rank": 5
},
{
"name": "Mikasa Ackerman",
"role": "Main",
"description": "Eren's adoptive sister and one of the main protagonists. After her parents were murdered, Eren saved her life and she has been protective of him ever since. She is considered an exceptionally skilled soldier.",
"voice_actor": "Yui Ishikawa (Japanese), Trina Nishimura (English)",
"image_url": "https://example.com/mikasa_ackerman.jpg",
"anime_title": "Attack on Titan",
"age": "15-19",
"gender": "Female",
"birth_date": date(835, 2, 10),
"height": "170 cm (5'7\")",
"weight": "68 kg (150 lbs)",
"blood_type": "Unknown",
"popularity_rank": 6
}
]
def init_db(db: Session) -> None:
# Create genres
for genre_data in INITIAL_GENRES:
genre = crud.genre.get_by_name(db, name=genre_data["name"])
if not genre:
genre_in = schemas.genre.GenreCreate(name=genre_data["name"])
crud.genre.create(db, obj_in=genre_in)
logger.info(f"Created genre: {genre_data['name']}")
# Create anime
anime_id_map = {} # Map anime titles to their IDs for character creation
for anime_data in INITIAL_ANIME:
anime = crud.anime.get_multi(db, limit=1, skip=0)
if not anime or all(a.title != anime_data["title"] for a in anime):
anime_in = schemas.anime.AnimeCreate(**anime_data)
created_anime = crud.anime.create_with_genres(db, obj_in=anime_in)
anime_id_map[anime_data["title"]] = created_anime.id
logger.info(f"Created anime: {anime_data['title']}")
else:
# Get the ID for existing anime
for a in anime:
if a.title == anime_data["title"]:
anime_id_map[anime_data["title"]] = a.id
# Create characters
for character_data in INITIAL_CHARACTERS:
# Get anime ID from title
anime_title = character_data.pop("anime_title")
if anime_title in anime_id_map:
character_data["anime_id"] = anime_id_map[anime_title]
# Check if character already exists to avoid duplicates
existing_characters = crud.character.get_by_anime(db, anime_id=character_data["anime_id"])
if not any(c.name == character_data["name"] for c in existing_characters):
character_in = schemas.character.CharacterCreate(**character_data)
crud.character.create(db, obj_in=character_in)
logger.info(f"Created character: {character_data['name']}")
def seed_data() -> None:
"""Seed initial data to the database."""
logger.info("Seeding initial data to the database")
db = SessionLocal()
try:
init_db(db)
finally:
db.close()
logger.info("Initial data seeded successfully")