Skip to content

skatsubo/immich-library-external-to-internal

Repository files navigation

Migrate Immich assets from external library to internal library

How to use | Caveats | Development

This is a proof of concept (PoC) for SQL-based conversion/migration of assets from external library into internal library (uploads).

Post-migration, images initially from external libraries will appear as if uploaded/imported into the internal library. But without re-uploading / re-import, thus preserving asset UUIDs and albums.

Why do that? Discussed in Upload and External library in same folder #19853.

How to use

  1. Clone the repo or download two files: migrate.sh and migrate-assets-external-to-internal.sql.

  2. Go to the Immich docker compose directory.

  3. Dry run (by default). It will create a history table with planned updates:

bash /path/to/repo/migrate.sh
  1. It will print its progress and instructions to follow.

Non-dry execution is only possible through SQL for safety reasons. Only do it on a test/throwaway Immich instance because the script is just PoC, see Caveats.

How to check history / planned changes

The history table:

SELECT * from migrate_assets_external_to_internal_history;

-[ RECORD 1 ]-----+--------------------------------------------------------------------------------------------
asset_id          | 67e5b712-7707-4caa-b871-c4b2e525ff82
old_originalpath  | /tmp/extvol/media/2025/2025-03/image.jpg
new_originalpath  | /data/library/admin/2025/2025-03/image.jpg
old_deviceassetid | image.jpg
new_deviceassetid | web-image.jpg-1753049128389
old_deviceid      | Library Import
new_deviceid      | Ext2int
old_isexternal    | t
new_isexternal    | f
is_skipped        | f
skip_reason       | 
cp_command        | cp "/tmp/extvol/media/2025/2025-03/image.jpg" "upload/library/admin/2025/2025-03/image.jpg"
mv_command        | mv "/tmp/extvol/media/2025/2025-03/image.jpg" "upload/library/admin/2025/2025-03/image.jpg"
update_sql        | UPDATE asset SET
                  |   "originalPath" = '/data/library/admin/2025/2025-03/image.jpg',
                  |   "deviceAssetId" = 'web-image.jpg-1753049128389',
                  |   "deviceId" = 'Ext2int',
                  |   "libraryId" = NULL,
                  |   "isExternal" = 'f'
                  | WHERE id = '67e5b712-7707-4caa-b871-c4b2e525ff82';
created_at        | 2025-07-20 22:05:28.388696+00

Caveats

Warning

This is a quick PoC. It is not secure against SQL injections, shell injections and other irregularities in data.

Direct altering of the Immich database as in this PoC is not recommended nor supported. Go with Immich API for production changes.

  • Updating checksum of migrated assets is not implemented (TODO). Therefore duplicate uploads will not be prevented if you re-upload some of those migrated assets again from mobile/web.
  • The script was updated to work with Immich version 1.137+. For older version see commit history.

Development

See README-DEV.md.

About

PoC of migrating Immich assets from external library to internal library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published