kdbxtool.merge

Database merge functionality for combining KDBX databases.

This module provides the Merger class for merging two KeePass databases following a UUID-based matching and timestamp-based conflict resolution algorithm similar to KeePassXC.

Example

>>> from kdbxtool import Database
>>> target = Database.open("main.kdbx", password="secret")
>>> source = Database.open("branch.kdbx", password="secret")
>>> result = target.merge(source)
>>> print(f"Added {result.entries_added} entries")
>>> target.save()

Classes

DeletedObject(uuid, deletion_time)

Record of a deleted entry or group.

MergeMode(*values)

Merge mode determining how conflicts and deletions are handled.

MergeResult([entries_added, ...])

Result of a database merge operation.

Merger(target, source, *[, mode])

Merges two KDBX databases with configurable conflict resolution.

class kdbxtool.merge.MergeMode(*values)[source]

Bases: Enum

Merge mode determining how conflicts and deletions are handled.

STANDARD

Add and update entries/groups from source. Does not delete anything from target. This is the default and safest mode.

SYNCHRONIZE

Full bidirectional sync including deletions. Items deleted in source (tracked in DeletedObjects) will be deleted from target if they haven’t been modified after the deletion time.

STANDARD = 1
SYNCHRONIZE = 2
class kdbxtool.merge.DeletedObject(uuid, deletion_time)[source]

Bases: object

Record of a deleted entry or group.

Used in SYNCHRONIZE mode to track deletions that should propagate to other databases during merge.

Parameters:
uuid

UUID of the deleted entry or group

Type:

uuid.UUID

deletion_time

When the deletion occurred

Type:

datetime.datetime

uuid: UUID
deletion_time: datetime
__init__(uuid, deletion_time)
Parameters:
Return type:

None

class kdbxtool.merge.MergeResult(entries_added=0, entries_updated=0, entries_relocated=0, entries_deleted=0, groups_added=0, groups_updated=0, groups_relocated=0, groups_deleted=0, history_entries_merged=0, binaries_added=0, custom_icons_added=0)[source]

Bases: object

Result of a database merge operation.

Contains detailed statistics about what was changed during the merge.

Parameters:
  • entries_added (int)

  • entries_updated (int)

  • entries_relocated (int)

  • entries_deleted (int)

  • groups_added (int)

  • groups_updated (int)

  • groups_relocated (int)

  • groups_deleted (int)

  • history_entries_merged (int)

  • binaries_added (int)

  • custom_icons_added (int)

entries_added

Number of new entries added from source

Type:

int

entries_updated

Number of existing entries updated (source was newer)

Type:

int

entries_relocated

Number of entries moved to different groups

Type:

int

entries_deleted

Number of entries deleted (SYNCHRONIZE mode only)

Type:

int

groups_added

Number of new groups added from source

Type:

int

groups_updated

Number of existing groups updated (source was newer)

Type:

int

groups_relocated

Number of groups moved to different parents

Type:

int

groups_deleted

Number of groups deleted (SYNCHRONIZE mode only)

Type:

int

history_entries_merged

Number of history entries added

Type:

int

binaries_added

Number of new binary attachments added

Type:

int

custom_icons_added

Number of new custom icons added

Type:

int

entries_added: int = 0
entries_updated: int = 0
entries_relocated: int = 0
entries_deleted: int = 0
groups_added: int = 0
groups_updated: int = 0
groups_relocated: int = 0
groups_deleted: int = 0
history_entries_merged: int = 0
binaries_added: int = 0
custom_icons_added: int = 0
property has_changes: bool

Check if any changes were made during the merge.

property total_changes: int

Total number of changes made.

summary()[source]

Get a human-readable summary of the merge result.

Return type:

str

__init__(entries_added=0, entries_updated=0, entries_relocated=0, entries_deleted=0, groups_added=0, groups_updated=0, groups_relocated=0, groups_deleted=0, history_entries_merged=0, binaries_added=0, custom_icons_added=0)
Parameters:
  • entries_added (int)

  • entries_updated (int)

  • entries_relocated (int)

  • entries_deleted (int)

  • groups_added (int)

  • groups_updated (int)

  • groups_relocated (int)

  • groups_deleted (int)

  • history_entries_merged (int)

  • binaries_added (int)

  • custom_icons_added (int)

Return type:

None

class kdbxtool.merge.Merger(target, source, *, mode=MergeMode.STANDARD)[source]

Bases: object

Merges two KDBX databases with configurable conflict resolution.

The merge algorithm follows these principles: 1. UUID-based matching: Entries and groups are matched by UUID 2. Timestamp-based resolution: Newer last_modification_time wins 3. History preservation: Losing versions are preserved in history 4. Location tracking: Entry moves are tracked via location_changed

Example

>>> merger = Merger(target_db, source_db)
>>> result = merger.merge()
>>> print(result.summary())
Parameters:
__init__(target, source, *, mode=MergeMode.STANDARD)[source]

Initialize the merger.

Parameters:
  • target (Database) – Database to merge into (will be modified)

  • source (Database) – Database to merge from (read-only)

  • mode (MergeMode) – Merge mode (STANDARD or SYNCHRONIZE)

Return type:

None

merge()[source]

Execute the merge operation.

Returns:

MergeResult with statistics about the merge

Raises:

MergeError – If merge fails

Return type:

MergeResult