Disclaimer: This documentation is provided for convenience and may contain errors. Always verify information against the official Kodi and provider documentation. Report issues.
Fastmail
Home / Kodi DB schema

Kodi MariaDB schema (MyVideos131)

The addon writes directly to Kodi's video database (MariaDB at 192.168.178.17:3306, DB MyVideos131) rather than going through Kodi's scanner. This page documents the tables and columns it touches — generated from real production rows + the INSERT INTO sites grep'd from library_sync.py.

Table map (everything the addon touches)

TableUsed forWritersReaders
pathOne row per source path (disk folder OR plugin URL)library_sync.ensure_*, _ensure_pathKodi library windows, Kodi scanner, library_sync._purge_stale_*
filesOne row per file. For EasyPlayTV rows: strFilename = the full plugin URL (same string as episode.c18 / movie.c22). For Kodi-scraped disk rows: strFilename = the basename.library_sync._insert_movie, _insert_episodeKodi player (resume + playCount), library_sync stale cleanup
movieOne row per movielibrary_sync._insert_movieKodi library windows, library_sync stale cleanup
tvshowOne row per serieslibrary_sync._insert_tvshow, prefix_existing_tvshows, fix_sort_titles, backfill_series_artKodi library windows, library_sync stale cleanup
seasonsOne row per (show, season_number)library_sync._ensure_seasonKodi library windows
episodeOne row per episodelibrary_sync._insert_episodeKodi library windows, library_sync stale cleanup
tvshowlinkpathMany-to-many between tvshow and path (a show can hang off multiple source paths)library_sync._insert_tvshowKodi scanner, library_sync
uniqueidProvider ids (tmdb / imdb / tvdb per media_id+type)library_sync._insert_movie, _insert_tvshow, _insert_episodeKodi scraper, library_sync de-dup checks
genre + genre_linkGenre table + linking to tvshow/movielibrary_sync._get_or_create_genre, _insert_tvshow, _insert_movieKodi library windows (genre tiles)
artImage rows (poster, fanart, thumb, season poster, episode still)library_sync._insert_movie, _insert_tvshow, _insert_episode, _ensure_season, backfill_series_artKodi UI (renders the artwork)
videoversionKodi 21's per-media-version row — every movie needs onelibrary_sync._insert_movieKodi's scanner
bookmarkResume points + play counts (via join to files.playCount)Kodi's playerKodi UI (resume bar, watch ticks)

The path row — the most important row in the schema for the addon

One row in path holds every file the addon manages. The addon relies on two path rows:

idPathstrPathstrContentstrScraperexcludePurpose
485plugin://plugin.video.easyplaytv/(varies — set to tvshows by ensure_series_path_config)metadata.tvshows.themoviedb.org.python1The plugin source path where every episode + movie file lives. exclude=1 stops Kodi's scanner from creating duplicate un-prefixed rows — see the warning in ensure_series_path_config.
3736/home/osmc/.kodi/.../Series/tvshowsmetadata.tvshows.themoviedb.org.python1The on-disk Series folder that used to hold .strm files. exclude=1 on this row means Kodi's scanner can't re-attach to it (or to any per-show sub-folder under it) and create duplicate un-prefixed rows; the only active source is the plugin path.
Path strContent flips between movies and tvshows

The single idPath=485 plugin row gets its strContent updated by both ensure_path_config (sets "movies") and ensure_series_path_config (sets "tvshows"). They run in different code paths and one overrides the other — currently whatever runs last wins. In practice this doesn't matter because the addon never relies on this column for routing (every query goes through showlink / file joins), but it's an inconsistency that could confuse a future Kodi scanner that reads it.

The tvshow table — column inventory (the addon cares about)

Kodi's tvshow table has 30+ columns. Most are huge XML blobs. The ones the addon writes:

ColumnWhat goes inWhy
c00"[ITVX] Ackley Bridge" (display title with prefix)Visible title. Sorts and search use c15 for the base name.
c01plot (overview)from TMDb
c05premiered (ISO date)from TMDb's first_air_date
c08XML blob of poster + backdropvia library_sync._build_thumbs
c09original title (display title without prefix)sort-by-original-name grouping
c10episodeguide JSON: {"tmdb":"12345","imdb":"tt…","tvdb":"…","…"}Required by Kodi's VideoInfoScanner before TMDb.GetEpisodeList — see warning in _insert_tvshow. If empty, episodes won't be fetched by Kodi's scan.
c11fanart XMLfrom library_sync._build_fanart
c12The uniqueid id for the tmdb uniqueid (set in the same INSERT flow after the uniqueid INSERT)Kodi uses c12 to point at the "primary" uniqueid. Required for the scanner.
c13MPAA rating ("Rated TV-14")TMDb content_ratings US branch
c14genre string ("Drama / Comedy")" / " - separated
c15sort title (display title stripped of [PROVIDER])set by library_sync.fix_sort_titles
c17IMDB id (legacy — also stored via uniqueid table)back-compat

The episode table

ColumnWhat
c00Episode display title in " - " format (when ep title differs from show)
c01plot
c04rating (TMDb vote_average)
c05votes
c06aired date (TMDb air_date)
c07thumb XML
c12season number (string)
c13episode number (string)
c18The play URL — the plugin://plugin.video.easyplaytv/?… link Kodi uses for playback
idFileFK to files.idFile — Kodi reads strFilename and the play URL from this joined row
idShow, idSeasonparent ids
c18 vs files.strFilename — the addon's different from Kodi's scanner

For Kodi's own disk-source rows (e.g. an Optima HTTP source), the two columns hold different shapes:

  • episode.c18 holds the full http://kodi:kodi@optima:80/Videos/Master/Series/24/Season 1/S01E01 - 12AM-1AM.mkv URL — what Kodi's player reads for play.
  • files.strFilename holds just the bare basename (S01E01 - 12AM-1AM.mkv) — what Kodi's library window displays as the filename column.

For EasyPlayTV's plugin-source rows, the addon writes the same full URL into both columns:

  • episode.c18 = plugin://plugin.video.easyplaytv/?action=resolve_vod&provider=bbc&episode_id=…
  • files.strFilename = the same full plugin URL.

There's no truncation in the addon's _insert_episode: the code at line 1136 simply aliases plugin_filename = strm_url and inserts that string into both files.strFilename and episode.c18. If a skin falls back to the filename column for an episode row whose c00 (title) is empty, the raw plugin://...?action=resolve_vod&... URL will leak through into the display. Movies have the same shape: movie.c22 = files.strFilename = full plugin URL.

The videoversion table (Kodi 21 addition)

Kodi 21 introduced the videoversion table to support multiple "versions" of a movie (theatrical cut, director's cut, etc.). The addon's library_sync._insert_movie INSERTs a single row with media_type='movie', idType=40400, itemType=0. idType=40400 is the canonical "default version" id for MyVideos131; if Kodi introduced a new version-type in a future schema, the addon would need to insert that one too. Without this row the movie shows in the library but can't be played through Kodi's UI navigation (it falls through to "no video version available").

Idempotency / collision queries