""" MTG Card Interaction Database Schema Defines the database schema for storing card interactions. Includes tables for synergies, counters, evolutions, and statistics. """ from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, ForeignKey, UniqueConstraint from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from datetime import datetime Base = declarative_base() class CardSynergy(Base): """ Synergy between two cards. Synergies are positive interactions where cards work well together. Examples: Archetype support, mechanic combos, mana base compatibility. """ __tablename__ = 'mtg_card_synergies' id = Column(Integer, primary_key=True, autoincrement=True) card_a_id = Column(Integer, ForeignKey('mtg_cards.id'), nullable=False) card_b_id = Column(Integer, ForeignKey('mtg_cards.id'), nullable=False) synergy_type = Column(String(50), nullable=False) # 'archetype', 'mechanic', 'mana', 'combo' strength = Column(Integer, nullable=False) # 1-5 (1=weak, 5=strong) notes = Column(String(500), nullable=True) confidence = Column(Float, nullable=False, default=0.8) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Unique constraint to prevent duplicates __table_args__ = ( UniqueConstraint('card_a_id', 'card_b_id', 'synergy_type', name='uq_synergy_pair_type'), ) # Relationships card_a = relationship('MtgCard', foreign_keys=[card_a_id]) card_b = relationship('MtgCard', foreign_keys=[card_b_id]) def __repr__(self): return f"" class CardCounter(Base): """ Counter relationship between two cards. Counters are negative interactions where one card is disadvantaged by another. Examples: Different color identities, outclassed stats, countered by specific spells. """ __tablename__ = 'mtg_card_counters' id = Column(Integer, primary_key=True, autoincrement=True) card_a_id = Column(Integer, ForeignKey('mtg_cards.id'), nullable=False) card_b_id = Column(Integer, ForeignKey('mtg_cards.id'), nullable=False) counter_type = Column(String(50), nullable=False) # 'color', 'stats', 'spell', 'keyword' strength = Column(Integer, nullable=False) # 1-5 (1=weak, 5=strong) notes = Column(String(500), nullable=True) confidence = Column(Float, nullable=False, default=0.7) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Unique constraint to prevent duplicates __table_args__ = ( UniqueConstraint('card_a_id', 'card_b_id', 'counter_type', name='uq_counter_pair_type'), ) # Relationships card_a = relationship('MtgCard', foreign_keys=[card_a_id]) card_b = relationship('MtgCard', foreign_keys=[card_b_id]) def __repr__(self): return f"" class CardEvolution(Base): """ Evolution relationship for a card. Evolutions track when a card has been reprinted, transformed, or evolved. Examples: Same name in different sets, transform pairs, double-sided cards. """ __tablename__ = 'mtg_card_evolution' id = Column(Integer, primary_key=True, autoincrement=True) card_id = Column(Integer, ForeignKey('mtg_cards.id'), nullable=False) evolved_card_id = Column(Integer, ForeignKey('mtg_cards.id'), nullable=False) evolution_type = Column(String(50), nullable=False) # 'reprint', 'transform', 'double_sided' strength = Column(Integer, nullable=False) # 1-5 (1=weak, 5=strong) notes = Column(String(500), nullable=True) confidence = Column(Float, nullable=False, default=0.9) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Unique constraint to prevent duplicates __table_args__ = ( UniqueConstraint('card_id', 'evolved_card_id', 'evolution_type', name='uq_evolution_pair_type'), ) # Relationships card = relationship('MtgCard', foreign_keys=[card_id]) evolved_card = relationship('MtgCard', foreign_keys=[evolved_card_id]) def __repr__(self): return f"" class CardInteractionStats(Base): """ Aggregated interaction statistics for a card. Tracks total interactions, average strength, and primary archetypes/themes. """ __tablename__ = 'mtg_card_interaction_stats' id = Column(Integer, primary_key=True, autoincrement=True) card_id = Column(Integer, ForeignKey('mtg_cards.id'), nullable=False, unique=True) # Interaction counts total_synergies = Column(Integer, nullable=False, default=0) total_counters = Column(Integer, nullable=False, default=0) total_evolutions = Column(Integer, nullable=False, default=0) total_partners = Column(Integer, nullable=False, default=0) # Cards that partner well # Mechanic/archetype counts total_mechanics = Column(Integer, nullable=False, default=0) total_archetypes = Column(Integer, nullable=False, default=0) total_themes = Column(Integer, nullable=False, default=0) # Synergy strength metrics avg_synergy_strength = Column(Float, nullable=False, default=0.0) max_synergy_strength = Column(Integer, nullable=False, default=0) # Primary archetype and theme primary_archetype = Column(String(50), nullable=True) primary_theme = Column(String(50), nullable=True) # Metadata created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) def __repr__(self): return f"" def create_interaction_tables(engine): """ Create all interaction tables in the database. Args: engine: SQLAlchemy engine """ Base.metadata.create_all(engine) print("āœ… Interaction tables created successfully") def drop_interaction_tables(engine): """ Drop all interaction tables from the database. Args: engine: SQLAlchemy engine """ Base.metadata.drop_all(engine) print("āœ… Interaction tables dropped successfully") if __name__ == "__main__": # Example usage from dotenv import load_dotenv import os load_dotenv() db_url = os.getenv('MTG_DATABASE_URL', 'postgresql+psycopg2://mtgonline:mtgonline_pass@172.18.0.2:5432/mtgdata') engine = create_engine(db_url) # Create tables create_interaction_tables(engine) # Print table names from sqlalchemy import inspect inspector = inspect(engine) print("\nšŸ“Š Tables created:") for table in inspector.get_table_names(): if 'mtg_card_' in table: print(f" - {table}")