3.6 KiB
Plex Library — Folder-Based Location Management via SQLite
When Plex groups compilation/VA folders together as "Various Artists" or cross-contaminates album metadata, the fix is to add each subfolder as an individual library location instead of a single parent folder.
The Problem
Plex treats a library's root folder as one namespace. If you have:
/Music/English/
├── Best of HipHop (2000-2026)/ ← compilation
├── Drake/ ← proper album
├── Green Day/ ← proper album
└── Today's Top Hits/ ← compilation
With respectTags=false, Plex uses folder names as album titles — compilation folders are fine but tagged albums get wrong metadata.
With respectTags=true, Plex uses embedded tags — tagged albums are correct, but compilation folders (which often have tracks with different "Album" tags from different sources) get grouped as "Various Artists" and cross-contaminated.
The Fix: Individual Locations
Add each subfolder as a separate library location. This makes Plex treat each folder as its own namespace — no cross-contamination.
Step 1: Check Current Locations
curl -s "http://192.168.50.98:32400/library/sections?X-Plex-Token=<TOKEN>" | grep -o '<Location[^>]*>'
Or via Python:
import urllib.request, xml.etree.ElementTree as ET
tree = ET.parse('/path/to/Preferences.xml')
token = tree.getroot().get('PlexOnlineToken')
url = f"http://localhost:32400/library/sections?X-Plex-Token={token}"
with urllib.request.urlopen(url) as resp:
print(resp.read().decode())
Pitfall: Bash mangles tokens with special characters. Use Python for all Plex API calls.
Step 2: List Subfolders
ls -1 /mnt/seagate8tb/Music/English/
Step 3: Add Each Subfolder as Location
Plex API for adding music library locations is unreliable (404s, auth issues). Use direct SQLite:
import sqlite3
db = "/home/ray/docker/plex/config/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db"
conn = sqlite3.connect(db)
base = "/mnt/seagate8tb/Music/English"
folders = ["Best of HipHop (2000-2026)", "Drake", "Green Day", ...]
for folder in folders:
path = f"{base}/{folder}"
conn.execute(
"INSERT INTO section_locations (library_section_id, root_path) VALUES (?, ?)",
(1, path) # 1 = library section ID
)
conn.commit()
conn.close()
Step 4: Remove Parent Location
conn.execute("DELETE FROM section_locations WHERE id=<parent_location_id>")
conn.commit()
Step 5: Restart and Scan
docker compose restart plex
Then trigger a scan (Python, not bash):
url = f"http://localhost:32400/library/sections/1/refresh?X-Plex-Token={token}"
urllib.request.urlopen(url)
Step 6: Verify
# Check if scan is running
grep -i "scan\|refresh" '/path/to/Plex Media Server.log' | tail -5
# Check scanner processes
ps aux | grep "Plex Media Scanner" | grep -v grep
DB Schema Reference
-- section_locations table
CREATE TABLE section_locations (
id INTEGER PRIMARY KEY,
library_section_id INTEGER,
root_path VARCHAR(255),
available BOOLEAN DEFAULT 't',
scanned_at INTEGER,
created_at INTEGER,
updated_at INTEGER
);
Tags vs Folder Names Tradeoff
respectTags=true— proper albums show correctly; compilations need the individual-location fixrespectTags=false— compilations show correctly as folder names; tagged albums get wrong metadata
With the individual-location fix, respectTags=true works for both cases.