poggers
This commit is contained in:
0
db/__init__.py
Normal file
0
db/__init__.py
Normal file
75
db/database.py
Normal file
75
db/database.py
Normal file
@@ -0,0 +1,75 @@
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.orm import sessionmaker, Session
|
||||
from contextlib import contextmanager
|
||||
from typing import Generator
|
||||
import os
|
||||
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Get database URL from environment variable with fallback
|
||||
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///omegacard.db")
|
||||
|
||||
# Create engine with proper configuration
|
||||
engine = create_engine(
|
||||
DATABASE_URL,
|
||||
pool_pre_ping=True, # Enable connection health checks
|
||||
pool_size=5, # Set reasonable pool size
|
||||
max_overflow=10 # Allow some overflow connections
|
||||
)
|
||||
|
||||
# Create session factory
|
||||
SessionLocal = sessionmaker(
|
||||
bind=engine,
|
||||
autocommit=False,
|
||||
autoflush=False
|
||||
)
|
||||
|
||||
@contextmanager
|
||||
def get_db_session() -> Generator[Session, None, None]:
|
||||
"""Context manager for database sessions"""
|
||||
session = SessionLocal()
|
||||
try:
|
||||
yield session
|
||||
except Exception as e:
|
||||
logger.error(f"Database session error: {str(e)}")
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
def get_db() -> Generator[Session, None, None]:
|
||||
"""Dependency for FastAPI to get database sessions"""
|
||||
with get_db_session() as session:
|
||||
yield session
|
||||
|
||||
def init_db() -> None:
|
||||
"""Initialize database tables"""
|
||||
from .models import Base
|
||||
try:
|
||||
Base.metadata.create_all(bind=engine)
|
||||
logger.info("Database tables created successfully")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize database: {str(e)}")
|
||||
raise
|
||||
|
||||
def check_db_connection() -> bool:
|
||||
"""Check if database connection is working"""
|
||||
try:
|
||||
with get_db_session() as session:
|
||||
session.execute(text("SELECT 1"))
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Database connection check failed: {str(e)}")
|
||||
return False
|
||||
|
||||
def destroy_db() -> None:
|
||||
"""Destroy all database tables"""
|
||||
from .models import Base
|
||||
try:
|
||||
Base.metadata.drop_all(bind=engine)
|
||||
logger.info("Database tables dropped successfully")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to destroy database: {str(e)}")
|
||||
raise
|
162
db/models.py
Normal file
162
db/models.py
Normal file
@@ -0,0 +1,162 @@
|
||||
from sqlalchemy import Column, Integer, String, Float, Boolean, DateTime, ForeignKey
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import relationship
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class Box(Base):
|
||||
__tablename__ = "boxes"
|
||||
|
||||
id = Column(String, primary_key=True, index=True)
|
||||
upload_id = Column(String, ForeignKey("upload_history.upload_id"))
|
||||
set_name = Column(String)
|
||||
set_code = Column(String)
|
||||
type = Column(String)
|
||||
cost = Column(Float)
|
||||
date_purchased = Column(DateTime)
|
||||
date_opened = Column(DateTime)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class ManaboxExportData(Base):
|
||||
__tablename__ = "manabox_export_data"
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
upload_id = Column(String)
|
||||
box_id = Column(String, nullable=True)
|
||||
name = Column(String)
|
||||
set_code = Column(String)
|
||||
set_name = Column(String)
|
||||
collector_number = Column(String)
|
||||
foil = Column(String)
|
||||
rarity = Column(String)
|
||||
quantity = Column(Integer)
|
||||
manabox_id = Column(String)
|
||||
scryfall_id = Column(String)
|
||||
purchase_price = Column(Float)
|
||||
misprint = Column(String)
|
||||
altered = Column(String)
|
||||
condition = Column(String)
|
||||
language = Column(String)
|
||||
purchase_price_currency = Column(String)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class UploadHistory(Base):
|
||||
__tablename__ = "upload_history"
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
upload_id = Column(String)
|
||||
filename = Column(String)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
status = Column(String)
|
||||
|
||||
class TCGPlayerGroups(Base):
|
||||
__tablename__ = 'tcgplayer_groups'
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
group_id = Column(Integer)
|
||||
name = Column(String)
|
||||
abbreviation = Column(String)
|
||||
is_supplemental = Column(String)
|
||||
published_on = Column(String)
|
||||
modified_on = Column(String)
|
||||
category_id = Column(Integer)
|
||||
|
||||
class TCGPlayerInventory(Base):
|
||||
__tablename__ = 'tcgplayer_inventory'
|
||||
|
||||
# TCGplayer Id,Product Line,Set Name,Product Name,Title,Number,Rarity,Condition,TCG Market Price,TCG Direct Low,TCG Low Price With Shipping,TCG Low Price,Total Quantity,Add to Quantity,TCG Marketplace Price,Photo URL
|
||||
id = Column(String, primary_key=True)
|
||||
export_id = Column(String)
|
||||
tcgplayer_product_id = Column(String, ForeignKey("tcgplayer_product.id"), nullable=True)
|
||||
tcgplayer_id = Column(Integer)
|
||||
product_line = Column(String)
|
||||
set_name = Column(String)
|
||||
product_name = Column(String)
|
||||
title = Column(String)
|
||||
number = Column(String)
|
||||
rarity = Column(String)
|
||||
condition = Column(String)
|
||||
tcg_market_price = Column(Float)
|
||||
tcg_direct_low = Column(Float)
|
||||
tcg_low_price_with_shipping = Column(Float)
|
||||
tcg_low_price = Column(Float)
|
||||
total_quantity = Column(Integer)
|
||||
add_to_quantity = Column(Integer)
|
||||
tcg_marketplace_price = Column(Float)
|
||||
photo_url = Column(String)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class TCGPlayerExportHistory(Base):
|
||||
__tablename__ = 'tcgplayer_export_history'
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
type = Column(String)
|
||||
pricing_export_id = Column(String)
|
||||
inventory_export_id = Column(String)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class TCGPlayerPricingHistory(Base):
|
||||
__tablename__ = 'tcgplayer_pricing_history'
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
tcgplayer_product_id = Column(String, ForeignKey("tcgplayer_product.id"))
|
||||
export_id = Column(String)
|
||||
group_id = Column(Integer)
|
||||
tcgplayer_id = Column(Integer)
|
||||
tcg_market_price = Column(Float)
|
||||
tcg_direct_low = Column(Float)
|
||||
tcg_low_price_with_shipping = Column(Float)
|
||||
tcg_low_price = Column(Float)
|
||||
tcg_marketplace_price = Column(Float)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class TCGPlayerProduct(Base):
|
||||
__tablename__ = 'tcgplayer_product'
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
group_id = Column(Integer)
|
||||
tcgplayer_id = Column(Integer)
|
||||
product_line = Column(String)
|
||||
set_name = Column(String)
|
||||
product_name = Column(String)
|
||||
title = Column(String)
|
||||
number = Column(String)
|
||||
rarity = Column(String)
|
||||
condition = Column(String)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class ManaboxTCGPlayerMapping(Base):
|
||||
__tablename__ = 'manabox_tcgplayer_mapping'
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
manabox_id = Column(String, ForeignKey("manabox_export_data.id"))
|
||||
tcgplayer_id = Column(Integer, ForeignKey("tcgplayer_inventory.tcgplayer_id"))
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class SetCodeGroupIdMapping(Base):
|
||||
__tablename__ = 'set_code_group_id_mapping'
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
set_code = Column(String)
|
||||
group_id = Column(Integer)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
class UnmatchedManaboxData(Base):
|
||||
__tablename__ = 'unmatched_manabox_data'
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
manabox_id = Column(String, ForeignKey("manabox_export_data.id"))
|
||||
reason = Column(String)
|
||||
date_created = Column(DateTime, default=datetime.now)
|
||||
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
23
db/utils.py
Normal file
23
db/utils.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from contextlib import contextmanager
|
||||
from sqlalchemy.orm import Session
|
||||
from exceptions import FailedUploadException
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@contextmanager
|
||||
def db_transaction(db: Session):
|
||||
"""Simple context manager for database transactions"""
|
||||
try:
|
||||
yield
|
||||
db.commit()
|
||||
except FailedUploadException as failed_upload:
|
||||
logger.error(f"Failed upload: {str(failed_upload.message)}")
|
||||
db.rollback()
|
||||
db.add(failed_upload.file_upload_record)
|
||||
db.commit()
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Database error: {str(e)}")
|
||||
db.rollback()
|
||||
raise
|
Reference in New Issue
Block a user