I forgot what I chanagerd
This commit is contained in:
1 parent
24081e1576
commit
c4f5018833
20 files changed
+678
-77
No files matched your search
@@ -1,12 +1,13 @@
|
||||
# package/database/__init__.py
|
||||
|
||||
# Expose components from individual modules using relative imports
|
||||
from .database import TwitchVideo, Data, YoutubeInfo, Database
|
||||
from .database import TwitchVideo, Data, YoutubeInfo, Chapter, Repository
|
||||
|
||||
# Explicitly define what is exposed when importing the subpackage
|
||||
__all__ = [
|
||||
"TwitchVideo",
|
||||
"Data",
|
||||
"YoutubeInfo",
|
||||
"Database",
|
||||
"Chapter",
|
||||
"Repository",
|
||||
]
|
||||
@@ -26,8 +26,12 @@ class TwitchVideo(Base):
|
||||
uploaded_yt_chats = Column(Boolean, nullable=False, default=False)
|
||||
uploaded_yt_shorts = Column(Boolean, nullable=False, default=False)
|
||||
|
||||
# Relationship back to YoutubeInfo (uselist=False enforces a 1-to-1 structure)
|
||||
youtube_info = relationship("YoutubeInfo", back_populates="twitch_video", uselist=False)
|
||||
# This now actually points to twitch_videos.id
|
||||
related_video_id = Column(String, ForeignKey("twitch_videos.id"), nullable=True)
|
||||
|
||||
# Relationship back to YoutubeInfo (uselist=True enforces a 1-to-many structure)
|
||||
youtube_info = relationship("YoutubeInfo", back_populates="twitch_video", uselist=True)
|
||||
chapters = relationship("Chapter", back_populates="twitch_video", cascade="all, delete-orphan")
|
||||
|
||||
# 3. Define the data table
|
||||
class Data(Base):
|
||||
@@ -43,7 +47,8 @@ class Data(Base):
|
||||
class YoutubeInfo(Base):
|
||||
__tablename__ = "youtube_info"
|
||||
|
||||
id = Column(String, ForeignKey("twitch_videos.id"), primary_key=True)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
twitch_video_id = Column(String, ForeignKey("twitch_videos.id"), nullable=False)
|
||||
yt_id = Column(String, nullable=True)
|
||||
yt_date = Column(String, nullable=True)
|
||||
yt_short_id = Column(String, nullable=True)
|
||||
@@ -56,8 +61,22 @@ class YoutubeInfo(Base):
|
||||
# Relationship linking back to the twitch video record
|
||||
twitch_video = relationship("TwitchVideo", back_populates="youtube_info")
|
||||
|
||||
class Chapter(Base):
|
||||
__tablename__ = "chapters"
|
||||
|
||||
class Database:
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
twitch_video_id = Column(String, ForeignKey("twitch_videos.id"), nullable=False)
|
||||
start_milliseconds = Column(Integer, nullable=False)
|
||||
length_milliseconds = Column(Integer, nullable=False)
|
||||
description = Column(String, nullable=True)
|
||||
type = Column(String, nullable=True)
|
||||
game_display_name = Column(String, nullable=True)
|
||||
game_id = Column(String, nullable=True)
|
||||
|
||||
# Relationship linking back to the twitch video record
|
||||
twitch_video = relationship("TwitchVideo", back_populates="chapters")
|
||||
|
||||
class Repository:
|
||||
def __init__(self, db_path: str = "database.db"):
|
||||
# 4. Connect to the SQLite file and generate the tables
|
||||
# This will create 'database.db' in the current working directory if it doesn't exist.
|
||||
@@ -68,6 +87,15 @@ class Database:
|
||||
Session = sessionmaker(bind=engine)
|
||||
self.session = Session()
|
||||
|
||||
def set_related_video(self, record_id: str, related_video_id: str):
|
||||
record = self.session.get(TwitchVideo, record_id)
|
||||
|
||||
if record:
|
||||
setattr(record, "related_video", related_video_id)
|
||||
self.session.commit()
|
||||
else:
|
||||
print(f"❌ Record {record_id} not found.")
|
||||
|
||||
def __mark_as(self, record_id: str, field_name: str, value: bool = True):
|
||||
record = self.session.get(TwitchVideo, record_id)
|
||||
|
||||
@@ -178,33 +206,67 @@ class Database:
|
||||
stmt = select(Data)
|
||||
return self.session.scalars(stmt).all()
|
||||
|
||||
def get_youtube_info(self, record_id) -> YoutubeInfo | None:
|
||||
return self.session.get(YoutubeInfo, record_id)
|
||||
def get_youtube_info_for_video(self, video_id: str) -> list[YoutubeInfo]:
|
||||
"""Retrieve all YouTubeInfo records associated with a specific TwitchVideo ID."""
|
||||
stmt = select(YoutubeInfo).where(YoutubeInfo.twitch_video_id == video_id)
|
||||
return self.session.scalars(stmt).all()
|
||||
|
||||
def insert(self, data: TwitchVideo | Data | YoutubeInfo):
|
||||
# SQLAlchemy 2.0 context manager handles commit/rollback automatically
|
||||
def get_youtube_info_all(self) -> list[YoutubeInfo]:
|
||||
return self.session.scalars(select(YoutubeInfo)).all()
|
||||
|
||||
def insert(self, data: TwitchVideo | Data | YoutubeInfo | Chapter):
|
||||
def insert(self, data: TwitchVideo | Data | YoutubeInfo | Chapter | list[YoutubeInfo] | list[Chapter]):
|
||||
"""
|
||||
Handles insertion/updating for any of the defined models,
|
||||
using session merge/add for SQLAlchemy 2.0 best practices.
|
||||
Accepts single objects or lists of objects for collection handling.
|
||||
"""
|
||||
try:
|
||||
if isinstance(data, TwitchVideo):
|
||||
# 1. Query for the existing row using SQLAlchemy 2.0 scalar execution
|
||||
# 1. Check if the record exists
|
||||
stmt = select(TwitchVideo).where(TwitchVideo.id == data.id)
|
||||
existing_record = self.session.scalar(stmt)
|
||||
|
||||
if existing_record:
|
||||
# 2. Update relevant fields on the managed instance
|
||||
if existing_record.view_count != data.view_count or existing_record.duration != data.duration:
|
||||
# 2. Update the columns on the managed instance
|
||||
existing_record.view_count = data.view_count
|
||||
existing_record.duration = data.duration
|
||||
print(f"🔄 Record {data.id} updated successfully!")
|
||||
print(f"🔄 TwitchVideo record {data.id} updated successfully!")
|
||||
# Note: Add more field updates here as needed
|
||||
else:
|
||||
# 3. Add new instance if it doesn't exist
|
||||
# 3. Add new instance
|
||||
self.session.add(data)
|
||||
print("➕ New TwitchVideo record inserted successfully!")
|
||||
else:
|
||||
print(f"➕ New TwitchVideo record with ID {data.id} inserted successfully!")
|
||||
elif isinstance(data, Data):
|
||||
self.session.merge(data)
|
||||
print(f"➕ {type(data).__name__} record inserted successfully!")
|
||||
# 4. Flush changes and commit the transaction
|
||||
self.session.commit()
|
||||
print(f"➕ Data record merged/inserted successfully!")
|
||||
elif isinstance(data, YoutubeInfo):
|
||||
# Handle single YoutubeInfo object
|
||||
self.session.merge(data)
|
||||
print(f"➕ YoutubeInfo record merged/inserted successfully!")
|
||||
elif isinstance(data, Chapter):
|
||||
# Handle single Chapter object
|
||||
self.session.merge(data)
|
||||
print(f"➕ Chapter record merged/inserted successfully!")
|
||||
elif isinstance(data, list):
|
||||
# Handle lists of records (YoutubeInfo or Chapter)
|
||||
record_type = type(data[0])
|
||||
if record_type in (YoutubeInfo, Chapter):
|
||||
for item in data:
|
||||
self.session.merge(item)
|
||||
print(f"➕ Successfully processed {len(data)} records of type {record_type.__name__}.")
|
||||
else:
|
||||
raise TypeError(f"Unsupported list content type: {record_type.__name__}")
|
||||
else:
|
||||
raise TypeError(f"Unsupported data type for insertion: {type(data).__name__}")
|
||||
|
||||
# 4. Commit the transaction
|
||||
self.session.flush() # Flush first to ensure IDs are populated
|
||||
|
||||
except Exception as e:
|
||||
self.session.rollback()
|
||||
print(f"❌ An error occurred, transaction rolled back: {e}")
|
||||
print(f"❌ A critical error occurred during record insertion/update: {e}")
|
||||
raise
|
||||
|
||||
self.session.commit()
|
||||
Reference in new issue
Block a user