.
Accessing Lightroom’s SQLite DB Directly

(This post is mostly for the search engines, to help others looking for the solution that this post provides)

Note that some of the details presented in this post, such as the database filename and the actual schema itself, are for the "beta 3" version of Lightroom, and don't apply to Lightroom Version 1.0 or later.

Lightroom, Adobe's high-volume photo workflow application, stores all kinds of user-preference and per-image data in an SQLite database. As of the Beta 3 release, the database is stored in one file, the Mac filename being /Users/username/Pictures/Lightroom/Lightroom B3 Library.aglib

If you're technically-minded and want to peek at the database directly, you might try to access it with the sqlite3 command, which comes standard with OSX, and be disappointed to find that it doesn't work:

$ sqlite3 'Lightroom B3 Library.aglib'
SQLite version 3.1.3
Enter ".help" for instructions
sqlite> .schema
Error: unsupported file format

Eric Scouten provided the answer in this thread on the Adobe's Lightroom Beta discussion forum. It turns out that Lightroom uses features of SQLite introduced in its version 3.2. OSX (as of 10.4.7) ships with SQLite version 3.1.3, and so it can't read Lightroom's database.

If you have Apple's XCode tools installed, you can download the source from sqlite.org and build a more recent version (3.3.6 is the latest as of this writing), and then it all works:

sqlite3 'Lightroom B3 Library.aglib'
SQLite version 3.3.6
Enter “.help” for instructions
sqlite> .schema
CREATE TABLE Adobe_AdditionalMetadata (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    image INTEGER,
    metadataPresetID,
    xmp
);
CREATE TABLE Adobe_FTPPresets (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    passive,
    password,
    path,
    port,
    protocol,
    server,
    title,
    username
);
CREATE TABLE Adobe_cameraRawSettings (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    name,
    rawSettings UNIQUE
);
CREATE TABLE Adobe_imageDevelopSettings (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    croppedHeight,
    croppedWidth,
    digest,
    fileHeight,
    fileWidth,
    grayscale INTEGER,
    historySettingsID,
    image INTEGER,
    settingsID,
    text,
    whiteBalance
);
CREATE TABLE Adobe_imageFiles (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    absolutePath NOT NULL DEFAULT '',
    idx_filename NOT NULL DEFAULT '',
    image INTEGER NOT NULL DEFAULT 0,
    importHash,
    lc_idx_filename NOT NULL DEFAULT '',
    markedMissing,
    md5,
    modTime,
    relativePath NOT NULL DEFAULT '',
    robustRepresentation
);
CREATE TABLE Adobe_imageProperties (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    image INTEGER,
    propertiesString
);
CREATE TABLE Adobe_images (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    aspectRatioCache,
    captureTime,
    developSettingsIDCache,
    fileHeight,
    fileWidth,
    hidden INTEGER NOT NULL DEFAULT 0,
    importedTime,
    orientation,
    originalCaptureTime,
    originalRootEntity INTEGER,
    panningDistanceH,
    panningDistanceV,
    photoBinNominators INTEGER,
    photoBinPosition,
    printSharpening,
    propertiesCache,
    pyramidIDCache,
    rating,
    rawSettings INTEGER,
    rootFile INTEGER,
    sidecarStatus
);
CREATE TABLE Adobe_libraryImageSavedSettings3 (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    dateCreated INTEGER,
    image INTEGER,
    isUserCheckpoint INTEGER NOT NULL DEFAULT 0,
    name,
    text,
    uuid
);
CREATE TABLE Adobe_namedIdentityPlate (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    description,
    identityPlate,
    identityPlateHash,
    moduleFont,
    moduleSelectedTextColor,
    moduleTextColor
);
CREATE TABLE Adobe_oldMetadataCache (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    image INTEGER,
    xmp
);
CREATE TABLE Adobe_variables (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    name,
    value
);
CREATE TABLE Adobe_variablesTable (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    name UNIQUE,
    value NOT NULL DEFAULT ''
);
CREATE TABLE AgLibraryContent (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    containingTag INTEGER,
    content,
    owningModule
);
CREATE TABLE AgLibraryImageSearchIndex (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    dirty INTEGER NOT NULL DEFAULT 0,
    image INTEGER NOT NULL DEFAULT 0,
    searchIndex
);
CREATE TABLE AgLibrarySpecialCollectionInfo (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    kind UNIQUE NOT NULL DEFAULT '',
    sortDirection,
    sortOrder
);
CREATE TABLE AgLibraryTag (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    dateCreated NOT NULL DEFAULT '',
    flattenedParams,
    genealogy NOT NULL DEFAULT '',
    imageCountFlag INTEGER NOT NULL DEFAULT 1,
    kindName NOT NULL DEFAULT '',
    lastApplied,
    name,
    parent INTEGER,
    sortDirection,
    sortOrder
);
CREATE TABLE AgLibraryTagImage (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    flagged,
    flattenedParams,
    image INTEGER NOT NULL DEFAULT 0,
    positionInCollection NOT NULL DEFAULT 'z',
    tag INTEGER NOT NULL DEFAULT 0,
    tagKind NOT NULL DEFAULT ''
);
CREATE TABLE AgLibraryTagSearchWord (
    id_local INTEGER PRIMARY KEY,
    id_global UNIQUE NOT NULL,
    implied INTEGER NOT NULL DEFAULT 0,
    tag INTEGER NOT NULL DEFAULT 0,
    word NOT NULL DEFAULT ''
);

sqlite> .quit
$

It would be prudent at this point to quote directly from Eric's post:

Of course, any mention of accessing the database file directly should come with the standard disclaimer that you're doing so at your own risk and you should make backup copies.

Comments so far....

I’m really happy to know SQLite is actually used for something significant. I’ve been plenty happy with DBD::SQLite2 for the past few months, as it gives me that sort of instant database I often find I want in my apps without most of the hassles of having to deal with an “actual” database.

— comment by Sam on August 10th, 2006 at 7:49am JST (2 years, 3 months ago) comment permalink
Leave a comment...

More or less plain text — see below for allowed markup

You can use the following tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>