lamindb.core.sync
¶
- lamindb.core.sync(*, registry, uid, source_db, transfer=None, depth=0)¶
Sync one object from a source database into the current database.
This function underlies
lamin io syncand wraps the lower-level.save()API:import lamindb as ln db = ln.DB("laminlabs/lamindata") db.Record.get("gL3TbX2qZQmCwTAU").save(transfer="annotations")
Guide: Transfer & sync across databases
- Parameters:
registry (
Registry) – Registry class, for exampleln.Artifactorln.Record.uid (
str) – UID of the object to sync.source_db (
str) – Source database slug, for examplelaminlabs/lamindata.transfer (
Literal['sqlrecord','notes','annotations'] |None, default:None) – ATransferMode. Omit it to use the registry default. Schema defaults toannotations.depth (
int, default:0) – How many levels of the type tree to transfer.0transfers only this object, plus the related objects selected bytransfer. Onlyrecord,feature,schema,project,ulabel, andreferenceacceptdepth > 0.
- Return type:
- Returns:
The saved
SQLRecordobject on the current database.
Traversing relationships¶
The
transferargument determines which related objects are transferred. If"sqlrecord", only the object with its required foreign keys are copied. If"notes", the object and its notes are copied. If"annotations", the object and its annotations are copied, that is, the object’s features, labels, and, for a schema, its members.How foreign keys land on the target¶
Most foreign keys are copied. When the related row is missing on the target, transfer creates it. A missing type is inserted as a stub. A
Recorddata record is the exception: transfer its type first, because that type carries the schema..runand.transformpoint at the transfer run on the target.space,branch, andcreated_onare handled differently from those foreign keys.spaceis mapped by uid. Transfer raisesNoWriteAccesswhen that space is not attached to the target database. Attach the space, then re-run the sync. Transfer does not create a space.branchandcreated_onare each mapped by uid when that branch already exists on the target. The built-in branchesmain,archive, andtrashalways do. When a uid is absent, that field is set to the current branch of the transfer. Transfer does not create a branch.
Example:
transfer="sqlrecord"on an artifact copies these foreign keys..runin the diagram is the transfer run on the target, not the source run.space,branch, andcreated_onfollow the rules above.flowchart TD artifact("Artifact"):::focal -->|storage| storage("Storage") artifact -->|created_by| user("User") artifact -->|run| run("Run") artifact -->|schema| schema("Schema")If you pass
transfer="annotations"upon transferring an artifact, its many-to-many relationships are transferred. Those contain all label & feature annotations but also inferred schemas via.schemas. Some of the many-to-many relationships of an artifact are shown below:flowchart TD artifact("Artifact"):::focal -->|ulabels| ulabels("ULabel") artifact -->|records| records("Record") artifact -->|projects| projects("Project") artifact -->|users| users("User") artifact -->|artifacts| linked("Artifact") artifact -->|schemas| schemas("Schema") artifact -->|json_values| json_values("JsonValue")The related objects themselves are transferred without their own annotations to avoid an infinite recursion. You have to transfer the related object itself if you want to transfer it with its own annotations.
Re-syncing¶
A sync operation is safe to repeat. UIDs already on the target database are mapped. A
Recordthat arrived earlier as a stub is filled in when you transfer that object itself. Links are replaced, not duplicated. So a first run withtransfer="sqlrecord"and a second run withtransfer="annotations"completes annotations.Every row this transfer writes has
.runset to a run of the transform__lamindb_transfer__/{source_database_uid}. To undo it, find that run and delete the objects whose.runis that run. Objects that were already on the target and only got mapped are not part of that run.