RomM Database Schema for ROMs: Complete SQLAlchemy Model Reference
RomM stores each game as a row in the roms table defined by the Rom SQLAlchemy model in backend/models/rom.py, featuring external provider IDs, file system metadata, JSON blobs for provider data, and relationships to platforms, user saves, and sibling variants.
RomM is a self-hosted ROM manager that organizes retro gaming collections using a structured database backend. The RomM database schema for ROMs centers on the Rom model class, which maps Python objects to relational tables using SQLAlchemy ORM. This article examines the complete schema definition, column types, indexes, and relationships as implemented in the rommapp/romm repository.
Core ROM Table Structure
The roms table serves as the central entity in the RomM database. Each row represents a single game entry with columns organized by function: identification, file system tracking, content metadata, and verification.
Primary and External Identifiers
Every ROM begins with an auto-incrementing primary key and integrates with multiple metadata providers through dedicated ID columns.
- id:
Integerprimary key with autoincrement - igdb_id, moby_id, ss_id, ra_id, launchbox_id, hasheous_id, tgdb_id:
Integercolumns for external provider integration - flashpoint_id:
String(100)for Flashpoint identifiers - gamelist_id, libretro_id:
String(64)for provider-specific string identifiers
File System Representation
RomM tracks the physical location and characteristics of ROM files using columns defined in backend/models/rom.py with length constants imported from backend/models/base.py.
- fs_name: Original file name as stored on disk
- fs_name_no_tags: Filename with tags stripped
- fs_name_no_ext: Filename without extension
- fs_extension: File extension only
- fs_path: Full directory path to the file
- fs_size_bytes:
BigIntegerrepresenting the file size in bytes
Content Metadata and Descriptions
Human-readable content and structured metadata from external providers use a mix of string and custom JSON types.
- name:
String(350)containing the human-readable title - slug:
String(400)for URL-friendly identifiers - summary:
Textfield for free-form game descriptions - igdb_metadata, moby_metadata, ss_metadata:
CustomJSONcolumns storing provider-specific blobs (genres, companies, ratings)
Media Assets and Verification
The schema tracks cover art, manuals, screenshots, and cryptographic hashes for integrity verification.
- path_cover_s, url_cover:
Textcolumns for local and remote cover art - path_manual, url_manual:
Textcolumns for manual storage locations - path_screenshots, url_screenshots:
CustomJSONlists for screenshot paths - crc_hash, md5_hash, sha1_hash, ra_hash:
String(100)checksums for verification and deduplication
Categorization and Status Fields
Versioning and organizational metadata support complex ROM sets with multiple revisions and regional variants.
- revision, version:
Stringcolumns for version tracking - regions, languages, tags:
CustomJSONlists for categorization - missing_from_fs:
Boolean(defaultFalse) flagging ROMs removed from the filesystem - platform_id:
Integerforeign key linking to theplatformstable
Database Relationships and Cardinality
The Rom model defines multiple relationships in backend/models/rom.py that link ROMs to platforms, files, user data, and other ROMs.
Platform Association
The platform relationship establishes a many-to-one link between ROMs and their parent platform (e.g., NES, SNES). The platform_id foreign key column enforces referential integrity to the platforms table.
File and Asset Relationships
Multi-file ROMs and associated assets are modeled through dedicated relationship properties:
- files: One-to-many relationship to
RomFilerepresenting individual files belonging to the ROM (main binary, M3U, manuals) - saves: One-to-many relationship to
Savefor user save files - states: One-to-many relationship to
Statefor emulator save states - screenshots: One-to-many relationship to
Screenshotfor captured gameplay images
User Data and Progress Tracking
Per-user data is isolated through intermediate tables:
- rom_users: One-to-many relationship to
RomUsertrackinglast_played,rating, andstatus - notes: One-to-many relationship to
RomNotefor user-generated notes with title, content, and visibility fields
Sibling ROMs and Collections
Regional variants and organizational grouping use many-to-many patterns:
- sibling_roms: Many-to-many self-referential relationship through the
sibling_romsassociation table for alternate versions/regional variants - collections: Many-to-many relationship to
Collectionvia thecollections_romsassociation table - metadatum: One-to-one relationship to
RomMetadatafor consolidated genre and franchise data
Supporting Tables in the Schema
The RomM database includes several satellite tables defined alongside the Rom model in backend/models/rom.py.
The rom_files Table
Individual files within a multi-file ROM are stored in the rom_files table with columns:
- id: Primary key
- rom_id: Foreign key to
roms.id - file_name, file_path, file_size_bytes: File system tracking
- Checksum columns for individual file verification
- category:
RomFileCategoryenum (e.g., main, manual, soundtrack) - archive_members:
CustomJSONfor archive contents - missing_from_fs: Boolean flag for file existence
Metadata Normalization with roms_metadata
The roms_metadata table normalizes JSON list data into a separate structure with rom_id as primary key, containing columns for genres, franchises, collections, companies, game_modes, and age_ratings.
User-Specific Tracking in rom_user
The rom_user table stores per-user ROM progress including last_played timestamps, star ratings, and completion status, linked via foreign key to the roms table.
Indexes and Query Optimizations
The schema includes strategic indexes defined in backend/models/rom.py to optimize common queries.
Unique Constraints
A unique composite index on (platform_id, fs_name) prevents duplicate filenames within the same platform, ensuring data integrity during scans.
Performance Indexes
Additional indexes accelerate metadata lookups:
- Indexes on provider ID columns (
igdb_id,moby_id, etc.) for external API synchronization - Index on
namefor search operations - Computed
name_sort_keycolumn for natural-sort ordering
Computed Column Properties
Deferred column properties optimize loading performance for expensive calculations:
- name_sort_key: Pre-computed natural sort key
- has_manual_files, has_soundtrack: Boolean indicators derived from
rom_filescorrelation - multi_file, top_level_file_count: Properties detecting multi-file ROM structures
Working with the RomM Schema
These examples demonstrate how to interact with the ROM schema using SQLAlchemy ORM.
Querying ROMs by Provider ID
from backend.models.rom import Rom
from sqlalchemy import select
def get_by_igdb(session, igdb_id: int):
"""Fetch ROM by IGDB identifier."""
stmt = select(Rom).where(Rom.igdb_id == igdb_id)
return session.scalars(stmt).first()
Accessing Relationships
# Load ROM with relationships
rom = session.get(Rom, 1)
# Access platform
print(rom.platform.name)
# List all files in multi-file ROM
for rom_file in rom.files:
print(f"{rom_file.file_name}: {rom_file.file_size_bytes} bytes")
# Check user progress
for user_data in rom.rom_users:
print(f"Rating: {user_data.rating}, Status: {user_data.status}")
Creating a New ROM Entry
from backend.models.rom import Rom
def add_rom(session, platform, file_name: str, file_path: str):
"""Create new ROM record."""
rom = Rom(
platform_id=platform.id,
fs_name=file_name,
fs_path=file_path,
name="Super Mario Bros.",
summary="Classic NES platformer",
)
session.add(rom)
session.commit()
return rom
Summary
- The RomM database schema for ROMs centers on the
romstable defined by theRomclass inbackend/models/rom.py - Each ROM tracks external provider IDs (IGDB, MobyGames, etc.), file system metadata, and JSON blobs for provider-specific data
- Relationships include many-to-one with Platform, one-to-many with RomFile/Save/State, and many-to-many with sibling ROMs and Collections
- Supporting tables (
rom_files,roms_metadata,rom_user) normalize file data, metadata tags, and user progress - A unique index on
(platform_id, fs_name)prevents duplicates, while computed properties likename_sort_keyoptimize sorting performance
Frequently Asked Questions
What is the primary key for ROMs in RomM?
The primary key is the id column, defined as an auto-incrementing Integer in the roms table. This internal identifier links to all related records in supporting tables like rom_files and rom_user, while external provider IDs (IGDB, MobyGames, etc.) exist as separate indexed columns for metadata synchronization.
How does RomM handle ROM variants and regional versions?
RomM uses a many-to-many self-referential relationship called sibling_roms linked through the sibling_roms association table. This allows regional variants, translations, and revision updates to reference each other as alternate versions of the same game, with metadata stored in JSON columns for regions and languages to distinguish variants.
Where are file checksums stored in the RomM schema?
Checksums reside in the main roms table within String(100) columns: crc_hash, md5_hash, sha1_hash, and ra_hash (RetroAchievements). For multi-file ROMs, individual file checksums are stored in the rom_files table alongside file-specific metadata, allowing verification at both the ROM and individual file level.
How does RomM track which files belong to a multi-file ROM?
The files relationship connects a Rom to multiple RomFile records in the rom_files table. Each RomFile entry tracks file_name, file_path, file_size_bytes, and checksums, with a category enum distinguishing between main binaries, manuals, and soundtracks. Computed properties multi_file and top_level_file_count determine ROM complexity without loading full file lists.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →