This script fills in names for detected faces when profile JPEGs encode <firstname>_<lastname> in their filename. It sets marker_name and subj_src=manual on matching face markers, then relies on photoprism faces update to create/link subjects and propagate to faces/markers.
- PhotoPrism running with MariaDB/MySQL.
mariadb(client) available inside the container (install if missing).- Originals path contains
Pictures/<firstname>_<lastname>.jpgfiles; each such JPEG shows one person. - Face detection already ran so a face marker exists for the file (typical after
photoprism index).
- Scans
Pictures/for files namedFirstname_Lastname.jpg(or .jpeg). - Parses
Firstname Lastname. - Finds the primary face marker for that file.
- If
subj_uidis empty, setsmarker_nameandsubj_src=manual(dry-run by default). - Reminds you to run
photoprism faces update --forceto create/link subjects and faces.
- Does not overwrite markers that already have
subj_uid. - Assumes exactly one face marker per target file.
- Requires an existing marker with embeddings; otherwise
faces updatecannot create a subject/face. - Runs a single-row
UPDATE ... LIMIT 1per file to prevent bulk mistakes.
Copy the script to your photoprism container, or place it in a mounted directory that is accessible from inside the container (such as the storage folder). Then, open a terminal, change to the directory where the script is located (e.g. cd storage), and ensure the script is executable (chmod 755 name-faces.sh).
./name-faces.shOutputs planned updates only.
./name-faces.sh --applyphotoprism faces update --force--applyperform updates (otherwise dry-run).--verboseextra diagnostics.
PHOTOPRISM_ORIGINALS_PATH(default/photoprism/originals)PHOTOPRISM_DATABASE_SERVER(defaultmariadb:3306)PHOTOPRISM_DATABASE_NAME(defaultphotoprism)PHOTOPRISM_DATABASE_USER(defaultroot)PHOTOPRISM_DATABASE_PASSWORD(required)
Example with custom DB host:
PHOTOPRISM_DATABASE_SERVER=db:3306 PHOTOPRISM_DATABASE_PASSWORD=secret ./name-faces.sh --apply- Subject creation is handled by
photoprism faces updateviaquery.CreateMarkerSubjects()which picks markers withmarker_name <> '',marker_type='face',subj_uid=''. - If you add logic (e.g., better filename parsing, multi-face support), ensure:
- You keep the guard
(m.subj_uid IS NULL OR m.subj_uid=''). - You don’t bypass
LIMIT 1. - You keep
marker_type='face'filter.
- You keep the guard
- Useful code references:
internal/entity/marker.go(SetName, SyncSubject, Face handling)internal/entity/query/subjects.go(CreateMarkerSubjects)internal/photoprism/faces.goandfaces_updatecommand wiring.
- Tables:
files— storesfile_name,file_uid,file_primary.markers— face markers (marker_uid,file_uid,marker_type='face',marker_name,subj_uid,subj_src,face_id).subjects— people records; created later byphotoprism faces update.
- Key query used by the script (simplified):
SELECT m.marker_uid, m.subj_uid FROM markers m JOIN files f ON f.file_uid=m.file_uid WHERE f.file_name=:filename AND f.file_primary=1 AND m.marker_type='face';UPDATE markers ... SET marker_name=:full_name, subj_src='manual' WHERE f.file_name=:filename AND f.file_primary=1 AND m.marker_type='face' AND (m.subj_uid IS NULL OR m.subj_uid='') LIMIT 1;
- Missing mariadb: install the MariaDB client in the container image.
- Pictures directory not found:
ensure
PHOTOPRISM_ORIGINALS_PATHpoints to the correct mount and thatPictures/exists. - No-op updates for a file:
likely the marker already has
subj_uidor the filename doesn’t match pattern. - After apply, still no subject:
photoprism faces update --force; if still empty, the marker may lack embeddings; re-run face detection or re-index that file.