2
\$\begingroup\$

I'm using digiKam 7.5 on an Ubuntu 22.04 system.

After upgrading my laptop's SSD to a larger one (to make more room for more photos of course :) ) by backing up my home directory and then restoring it on the new drive digiKam thinks the drive containing the album has disappeared, in spite of them being at exactly the same path, since the volume's UUID changed.

How can I convince digiKam that my photos are, in fact, still where I left them?

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

I found an old mail thread from 2011 and some bugs (267131, 456749) that discuss a similar issue. It also seemed to suggest how the digiKam database could be updated to fix the issue.

It seems that, even for non-removable drives, digiKam considers the volume's UUID to be part of the file path to the album. A new filesystem created on a new drive will have a differnt UUID even though it contains the same data as the old. For each root album digiKam stores, in its sql database, a record like:

.headers on
select * from AlbumRoots limit 10;
id|label|status|type|identifier|specificPath
1|digikam|0|1|volumeid:?uuid=90ee45ae-cd07-4e23-a948-7ddf8afff45f|/home/brick/Pictures/digikam

It combines the volume UUID from the identifier column with the path in the specificPath column to decide where to look for files. If it does not find a volume with the specified UUID it considers the album to be missing.

Summarily, fixing it involves:

  1. Use the blkid command to find the UUID of your new volume
  2. Use the sqlite3 command to open digiKam's database
  3. Update the offending AlbumRoot record to the new disk's UUID.
  4. Alternatively, change the AlbumRoot to a UUID-free rubric. Should avoid similar issues going forward, but also seemed to be necessary if using a ZFS based filesystem since digiKam does not seem to pick up the UUID.

1. Getting the new UUID

On my system blkid gave:

$ blkid
/dev/sda4: LABEL="rpool" UUID="8788856976958701461" UUID_SUB="2923538069334769741" BLOCK_SIZE="4096" TYPE="zfs_member" PARTUUID="24ffc0e5-7b57-9940-8526-e267bf4e194a"
/dev/sda2: UUID="a59d3973-47b8-42ec-9d64-755553a7bb33" TYPE="swap" PARTUUID="4a88d048-d33e-0142-bed0-14bc7d1a5e34"
/dev/sda3: LABEL="bpool" UUID="11746124927107044680" UUID_SUB="12202475822180589330" BLOCK_SIZE="4096" TYPE="zfs_member" PARTUUID="252ae807-f008-d54a-a63d-3b9df9dfff1e"
/dev/sda1: UUID="DB82-0239" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="dbb46316-3caf-4f7b-b26c-dde89c848141"

I moved to using a ZFS root directory, so the /dev/sda4: LABEL="rpool" ... entry's PARTUUID="24ffc0e5-7b57-9940-8526-e267bf4e194a" section gives me the required UUID.

2. Open the digiKam database

First ensure you have sqlite3 installed by running, in a terminal:

sudo apt install sqlite3

You need to find the file named digikam4.db. Where this file lives will be up to how you installed digiKam. TBH I'm not exactly sure how to easily and reliably find this file, but I knew mine was stored in the same directory as my first album.

Before you go further, quit digiKam (make sure you got all the windows) and make a backup of the database file in case you break it with the updates. In my case, in a terminal:

cp /home/brick/Pictures/digikam/digikam4.db cp /home/brick/Pictures/digikam/digikam4.db.backup

Then open the database file with sqlite3 in a terminal:

sqlite3 /home/brick/Pictures/digikam/digikam4.db

3. Fix the UUID using sqlite3

Find the current (problematic) AlbumRoot (the .headers line is optional but makes it easier to see what is going on) by typing in the sqlite3 terminal session:

.headers on
select * from AlbumRoots limit 10;

In my case this returned a single record:

id|label|status|type|identifier|specificPath
1|digikam|0|1|volumeid:?uuid=90ee45ae-cd07-4e23-a948-7ddf8afff45f|/home/brick/Pictures/digikam

Now we replace the UUID by the one we found in step 1 using blkid, in my case 24ffc0e5-7b57-9940-8526-e267bf4e194a in the sqlite3 terminal session:

update AlbumRoots set identifier = 'volumeid:?uuid=24ffc0e5-7b57-9940-8526-e267bf4e194a' where identifier = 'volumeid:?uuid=90ee45ae-cd07-4e23-a948-7ddf8afff45f';

I added the where clause just from the habit of never doing unqualified SQL update statements. If you had multiple album roots this would prevent you from breaking other records that were correct.

So, templated the update would be

update AlbumRoots set identifier = 'volumeid:?uuid=<NEW UUID>' where identifier = 'volumeid:?uuid=<OLD UUID>'

Now you should be done. Start up digiKam and, hopefully, everything is as it should be.

4. Alternative ending to 3. without using UUID

I had updated my filesystem from ext4 to ZFS and, even when I made this fix, digiKam still did not recognize my album. With a bit of experimentation (adding another album) it seems that digiKam does not recognise the UUID of my ZFS partition and, instead, created an AlbumRoot entry in a UUID-free format. I then converted my main album to the same format by doing, in the sqlite3 terminal session:

update AlbumRoots set identifier = 'volumeid:?path=/home/brick/Pictures/digikam' where specificPath = '/home/brick/Pictures/digikam';
update AlbumRoots set specificPath = '/' where specificPath = '/home/brick/Pictures/digikam';

Afterwards the AlbumRoots table looked like this:

sqlite> select * from AlbumRoots limit 10;
id|label|status|type|identifier|specificPath
1|digikam|0|1|volumeid:?path=/home/brick/Pictures/digikam|/

In summary, the identifier column becomes volumeid:?path=<absolute_path_to_your_album> and the specificPath column simply becomes /.

Q: Why do it this way? A: You won't run into a similar issue if you upgrade your drive again, as long as you always store the same album in the same absolute path. If you are using ZFS it seems you have no choice.

Q: Why not do it this way? A: For albums on removable drives digiKam won't be able to disambiguate between different physical drives that happen to be mounted at the same, temporary, mount point. For Albums on your fixed / internal drive it should be absolutely fine though.

\$\endgroup\$
1
  • \$\begingroup\$ This is a fantastic answer, which saved my 20-year-old collection after switching to a new laptop with the fresh openSUSE BTRFS-based install. BTW, there's a small error in templated update, it should read update AlbumRoots set identifier = 'volumeid:?uuid=<NEW UUID>' where identifier = 'volumeid:?uuid=<OLD UUID>'. The reason for the ZFS parttion not working with the first solution might be that the specific paths are relative to the UUID-marked partition mount point, so most likely you'd need to remove /home from specific paths assuming it's mounted there. \$\endgroup\$ Commented May 20 at 18:50
1
\$\begingroup\$

Following NeilenMarais's excellent answer I wrote a simple Bash script to update the UUID, picture and icon paths:

#!/bin/bash

# convert a digiKam database after moving pictures to the new location

if [[ -z $1 ]]; then
    db=~/Pictures/digikam4.db
else
    db=$1
fi

old_uuid=cd1bd0ba-8224-4e1a-a1d0-6dcec256e363
new_uuid=d2e62c13-7f76-41c8-864e-0dde045cca10

old_pics_path=/luke/Pictures
new_pics_path=/home/lukasz/Pictures

old_icons_path=/home/luke/install/icons
new_icons_path=/home/lukasz/icons

sqlite3 "$db" <<- EOF
    update AlbumRoots set identifier = 'volumeid:?uuid=$new_uuid' where identifier = 'volumeid:?uuid=$old_uuid';
    update AlbumRoots set specificPath = '$new_pics_path' where specificPath = '$old_pics_path';
    update Tags set iconkde = replace(iconkde, '$old_icons_path', '$new_icons_path');
EOF
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.