Transfer data
¶
This guide shows how to transfer data from a source database to your default database.
# pip install lamindb
!lamin init --storage ./test-transfer --modules bionty
Show code cell output
! using anonymous user (to identify, call: lamin login)
→ initialized lamindb: anonymous/test-transfer
import lamindb as ln
ln.track()
Show code cell output
→ connected lamindb: anonymous/test-transfer
→ created Transform('4ZWJ65p24zUy0000', key='transfer.ipynb'), started new Run('u2xVdvRsWimWR2nz') at 2026-02-16 07:28:42 UTC
→ notebook imports: lamindb==2.2a1
• recommendation: to identify the notebook across renames, pass the uid: ln.track("4ZWJ65p24zUy")
Query artifacts in the laminlabs/lamindata instance:
db = ln.DB("laminlabs/lamindata")
artifacts = db.Artifact.filter(is_latest=True) # query latest versions of artifacts
artifacts.to_dataframe()
Show code cell output
| uid | key | description | suffix | kind | otype | size | hash | n_files | n_observations | ... | is_latest | is_locked | created_at | branch_id | created_on_id | space_id | storage_id | run_id | schema_id | created_by_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||
| 14607 | 6aJeGrwRR3tK21N50000 | None | Output artifact for run 3457 | .json | None | None | 136.0 | A8ak2Xrd1RebUooxaK57Tg | None | None | ... | True | False | 2026-02-15 05:33:21.170875+00:00 | 1 | 1 | 1 | 2 | 3457 | None | 18 |
| 14606 | yzb2fEF1g60Zt2bc0000 | None | Output artifact for run 3457 | .json | None | None | 136.0 | ExOqeccwrVTMNJfQmiXBxA | None | None | ... | True | False | 2026-02-15 05:33:18.970024+00:00 | 1 | 1 | 1 | 2 | 3457 | None | 18 |
| 14605 | mRqA1ysNSnhCSsTG0000 | None | Output artifact for run 3456 | .json | None | None | 136.0 | r7DBfZY4U1iWOZkQcXkqwg | None | None | ... | True | False | 2026-02-15 05:33:09.288061+00:00 | 1 | 1 | 1 | 2 | 3456 | None | 18 |
| 14604 | W4ousIeYABSVG71N0000 | None | Output artifact for run 3456 | .json | None | None | 136.0 | nO-y7TeqbD8A47_0gShfrw | None | None | ... | True | False | 2026-02-15 05:33:03.997365+00:00 | 1 | 1 | 1 | 2 | 3456 | None | 18 |
| 14603 | 2IlBqs6kybIUPdmK0000 | None | Output artifact for run 3453 | .json | None | None | 136.0 | k4e3IpXwADTnoL6LPbES2w | None | None | ... | True | False | 2026-02-14 05:27:06.863630+00:00 | 1 | 1 | 1 | 2 | 3453 | None | 18 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 14207 | RmhdZhnrYdQ1Zc3K0000 | None | Output artifact for run 3197 | .json | None | None | 136.0 | QCzF8LnIMFrqQCZYR5roSQ | None | None | ... | True | False | 2026-02-11 10:46:23.601987+00:00 | 1 | 1 | 1 | 2 | 3197 | None | 18 |
| 14206 | xhDZ6wPsZNah6rsj0000 | scratch/temp-lamin/temp-bgzip/run_20260211_113... | Output artifact for run 3194 | .txt.bgz | None | None | 3957.0 | AIZcTqOTmEnFkD8Qf8TXjA | None | None | ... | True | False | 2026-02-11 10:40:33.953257+00:00 | 1 | 1 | 1 | 33 | 3193 | None | 28 |
| 14205 | qG6bUzTdGEDzkIte0000 | None | Input artifact at file:///home/rcannood/worksp... | None | None | 11324.0 | 3L8lOz1tCa5-ZMs0tNDsMw | None | None | ... | True | False | 2026-02-11 10:40:08.756730+00:00 | 1 | 1 | 1 | 2 | None | None | 28 | |
| 14204 | urpM4vzfY9n463Sr0000 | scratch/temp-lamin/temp-bgzip/run_20260211_113... | Output artifact for run 3192 | .txt.bgz | None | None | 902213.0 | VdsUgDh/InXtOZGGgsX41w | None | None | ... | True | False | 2026-02-11 10:36:53.969729+00:00 | 1 | 1 | 1 | 33 | 3192 | None | 28 |
| 14201 | kmbz7dDVt0Jl8lop0000 | None | Output artifact for run 3188 | .json | None | None | 136.0 | 67EbrT_eI5LNsT6XD0j-tQ | None | None | ... | True | False | 2026-02-11 05:39:39.675519+00:00 | 1 | 1 | 1 | 2 | 3188 | None | 18 |
100 rows × 21 columns
You can now further subset or search the QuerySet. Here we already know what we’re looking for:
artifact = artifacts.get(key="example_datasets/mini_immuno/dataset1.h5ad")
artifact.describe()
Show code cell output
Artifact: example_datasets/mini_immuno/dataset1.h5ad (0000) | description: Flow cytometry readouts on invitro cell culture ├── uid: 9K1dteZ6Qx0EXK8g0000 run: VioVE27 (curate-anndata-mini-immuno.ipynb) │ kind: dataset otype: AnnData │ hash: FB3CeMjmg1ivN6HDy6wsSg size: 30.9 KB │ branch: main space: all │ created_at: 2025-07-29 12:27:25 UTC created_by: falexwolf │ n_observations: 3.0 ├── storage/path: s3://lamindata/.lamindb/9K1dteZ6Qx0EXK8g0000.h5ad ├── Dataset features │ ├── obs (8.0) │ │ assay_oid bionty.ExperimentalFactor.ontology… EFO:0008913 │ │ cell_type_by_expert bionty.CellType B cell, CD8-positive, alpha-beta T cell │ │ cell_type_by_model bionty.CellType B cell, T cell │ │ concentration str │ │ donor str │ │ perturbation ULabel DMSO, IFNG │ │ sample_note str │ │ treatment_time_h num │ └── var.T (3.0 bionty.Gene.ensem… │ CD14 num │ CD4 num │ CD8A num ├── External features │ └── experiment Record[6pjoBrrz4f1EzQMO] EXP-scRNA-002 │ experiment ULabel Experiment 1 │ date_of_study date 2024-12-01 │ study_metadata dict {'detail1': '123', 'detail2': 1} │ study_note str We had a great time performing this st… │ temperature float 21.6 └── Labels └── .ulabels ULabel DMSO, IFNG, Experiment 1 .records Record EXP-scRNA-002 .projects Project Tutorials .cell_types bionty.CellType B cell, T cell, CD8-positive, alpha-be… .experimental_factors bionty.ExperimentalFactor single-cell RNA sequencing
By saving the artifact that’s currently attached to the source database, you transfer it to your default database.
artifact.save()
Show code cell output
→ transferred: Artifact(uid='9K1dteZ6Qx0EXK8g0000'), Storage(uid='D9BilDV2'), Schema(uid='0000000000000002')
Artifact(uid='9K1dteZ6Qx0EXK8g0000', version_tag=None, is_latest=True, key='example_datasets/mini_immuno/dataset1.h5ad', description='Flow cytometry readouts on invitro cell culture', suffix='.h5ad', kind='dataset', otype='AnnData', size=31672.0, hash='FB3CeMjmg1ivN6HDy6wsSg', n_files=None, n_observations=3.0, branch_id=1, created_on_id=1, space_id=1, storage_id=2, run_id=2, schema_id=1, created_by_id=1, created_at=2025-07-29 12:27:25 UTC, is_locked=False)
How do I know if an object is saved in the default database or not?
Every SQLRecord object has an attribute ._state.db which can take the following values:
None: the object has not yet been saved to any database"default": the object is saved on the default database instance"account/name": the object is saved on a non-default database instance referenced byaccount/name(e.g.,laminlabs/lamindata)
The artifact has been transferred to the current database without feature & label annotations, but with updated data lineage:
artifact.describe()
Show code cell output
Artifact: example_datasets/mini_immuno/dataset1.h5ad (0000) | description: Flow cytometry readouts on invitro cell culture ├── uid: 9K1dteZ6Qx0EXK8g0000 run: VpiTmji (__lamindb_transfer__/4XIuR0tvaiXM) │ kind: dataset otype: AnnData │ hash: FB3CeMjmg1ivN6HDy6wsSg size: 30.9 KB │ branch: main space: all │ created_at: 2025-07-29 12:27:25 UTC created_by: anonymous │ n_observations: 3 └── storage/path: s3://lamindata/.lamindb/9K1dteZ6Qx0EXK8g0000.h5ad
The data itself remained in the original storage location, which has been added to your default database’s storage location as a read-only location. This is indicated by the fact that the instance_uid does not match the uid of your default database.
ln.Storage.to_dataframe()
Show code cell output
| uid | root | description | type | region | instance_uid | is_locked | created_at | branch_id | created_on_id | space_id | created_by_id | run_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||
| 2 | D9BilDV2 | s3://lamindata | None | s3 | us-east-1 | 4XIuR0tvaiXM | False | 2023-04-22 05:50:06.537267+00:00 | 1 | 1 | 1 | 1 | 2.0 |
| 1 | onCrRa7LR0ft | /home/runner/work/lamindb/lamindb/docs/test-tr... | None | local | None | 1FHu5eE0uxm4 | False | 2026-02-16 07:28:38.621000+00:00 | 1 | 1 | 1 | 1 | NaN |
See the state of the database:
ln.view()
Show code cell output
****************
* module: core *
****************
Artifact
| uid | key | description | suffix | kind | otype | size | hash | n_files | n_observations | ... | is_latest | is_locked | created_at | branch_id | created_on_id | space_id | storage_id | run_id | schema_id | created_by_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||
| 1 | 9K1dteZ6Qx0EXK8g0000 | example_datasets/mini_immuno/dataset1.h5ad | Flow cytometry readouts on invitro cell culture | .h5ad | dataset | AnnData | 31672 | FB3CeMjmg1ivN6HDy6wsSg | None | 3 | ... | True | False | 2025-07-29 12:27:25.572900+00:00 | 1 | 1 | 1 | 2 | 2 | 1 | 1 |
1 rows × 21 columns
Run
| uid | name | description | entrypoint | started_at | finished_at | params | reference | reference_type | cli_args | ... | created_at | branch_id | created_on_id | space_id | transform_id | report_id | environment_id | plan_id | created_by_id | initiated_by_run_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||
| 2 | VpiTmjiQoZ5HQUr7 | None | None | None | 2026-02-16 07:28:46.550000+00:00 | None | None | None | None | None | ... | 2026-02-16 07:28:46.550000+00:00 | 1 | 1 | 1 | 2 | None | None | None | 1 | 1.0 |
| 1 | u2xVdvRsWimWR2nz | None | None | None | 2026-02-16 07:28:42.351144+00:00 | None | None | None | None | None | ... | 2026-02-16 07:28:42.352000+00:00 | 1 | 1 | 1 | 1 | None | None | None | 1 | NaN |
2 rows × 21 columns
Schema
| uid | name | description | n_members | coerce | flexible | itype | otype | hash | minimal_set | ... | maximal_set | is_locked | is_type | created_at | branch_id | created_on_id | space_id | created_by_id | run_id | type_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||
| 1 | 0000000000000002 | anndata_ensembl_gene_ids_and_valid_features_in... | None | None | None | True | Composite | AnnData | UR_ozz2VI2sY8ckXop2RAg | True | ... | False | False | False | 2025-07-10 10:21:07.781328+00:00 | 1 | 1 | 1 | 1 | 2 | None |
1 rows × 21 columns
Storage
| uid | root | description | type | region | instance_uid | is_locked | created_at | branch_id | created_on_id | space_id | created_by_id | run_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||
| 2 | D9BilDV2 | s3://lamindata | None | s3 | us-east-1 | 4XIuR0tvaiXM | False | 2023-04-22 05:50:06.537267+00:00 | 1 | 1 | 1 | 1 | 2.0 |
| 1 | onCrRa7LR0ft | /home/runner/work/lamindb/lamindb/docs/test-tr... | None | local | None | 1FHu5eE0uxm4 | False | 2026-02-16 07:28:38.621000+00:00 | 1 | 1 | 1 | 1 | NaN |
Transform
| uid | key | description | kind | source_code | hash | reference | reference_type | version_tag | is_latest | is_locked | created_at | branch_id | created_on_id | space_id | environment_id | plan_id | created_by_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | ||||||||||||||||||
| 2 | 4XIuR0tvaiXM0000 | __lamindb_transfer__/4XIuR0tvaiXM | Transfer from `laminlabs/lamindata` | function | None | None | None | None | None | True | False | 2026-02-16 07:28:46.544000+00:00 | 1 | 1 | 1 | None | None | 1 |
| 1 | 4ZWJ65p24zUy0000 | transfer.ipynb | Transfer data [
Show code cell output
! calling anonymously, will miss private instances
The transferred dataset is linked to a special type of transform that stores the slug and uid of the source instance:
artifact.transform.description
Show code cell output
'Transfer from `laminlabs/lamindata`'
The transform key has the form f"__lamindb_transfer__/{source_instance.uid}":
artifact.transform.key
Show code cell output
'__lamindb_transfer__/4XIuR0tvaiXM'
The current notebook run is linked as the initiated_by_run of the “transfer run”:
artifact.run.initiated_by_run.transform
Show code cell output
Transform(uid='4ZWJ65p24zUy0000', version_tag=None, is_latest=True, key='transfer.ipynb', description='Transfer data [](https://github.com/laminlabs/lamindb/blob/main/docs/transfer.md)', kind='notebook', hash=None, reference=None, reference_type=None, environment=None, plan=None, branch_id=1, created_on_id=1, space_id=1, created_by_id=1, created_at=2026-02-16 07:28:42 UTC, is_locked=False)
Upon re-transferring a record, it will identify that the record already exists in the target database and simply map the record.
artifact = artifacts.get(key="example_datasets/mini_immuno/dataset1.h5ad")
artifact.save()
Show code cell output
→ mapped: Artifact(uid='9K1dteZ6Qx0EXK8g0000')
Artifact(uid='9K1dteZ6Qx0EXK8g0000', version_tag=None, is_latest=True, key='example_datasets/mini_immuno/dataset1.h5ad', description='Flow cytometry readouts on invitro cell culture', suffix='.h5ad', kind='dataset', otype='AnnData', size=31672, hash='FB3CeMjmg1ivN6HDy6wsSg', n_files=None, n_observations=3, branch_id=1, created_on_id=1, space_id=1, storage_id=2, run_id=2, schema_id=1, created_by_id=1, created_at=2025-07-29 12:27:25 UTC, is_locked=False)
If you also want to transfer annotations of the artifact, you can pass transfer="annotations" to save(). Just note that this might populate your target database with metadata that doesn’t match the conventions you want to enforce.
artifact = artifacts.get(key="example_datasets/mini_immuno/dataset1.h5ad")
artifact.save(transfer="annotations")
Show code cell output
→ mapped: Artifact(uid='9K1dteZ6Qx0EXK8g0000'), CellType(uid='ryEtgi1yGtAcX2'), CellType(uid='22LvKd01YyNA1a'), CellType(uid='6IC9NGJEv2Y4TD'), CellType(uid='ryEtgi1yGtAcX2'), ExperimentalFactor(uid='4WYv9kl0W2SroY')
→ transferred: Feature(uid='LIrjN9FbaLR1'), Feature(uid='xFdXre6ZPLlK'), Feature(uid='fJnNc4pzxe9c'), Feature(uid='7xDpJZiVLRl3'), Feature(uid='BaPfsAPgDFrT'), Feature(uid='DLeKfqUbrUsg'), Feature(uid='zvyDVbZln36o'), Feature(uid='Q8edF7CSgjG2'), Organism(uid='1dpCL6TduFJ3AP'), Source(uid='4BENqfHn'), Source(uid='404rkf5M'), Gene(uid='1j4At3x7akJU8n'), Gene(uid='6Aqvc8ckDYeNrD'), Gene(uid='3bhNYquOnA4sdo'), ULabel(uid='vmjLLqYy'), ULabel(uid='YAhFIvh5'), ULabel(uid='Yis4YLIB'), ULabel(uid='InLummy0'), Feature(uid='4ycwa8er0EB2'), Record(uid='ZRP07Y49Ni3Ne0Ae'), Record(uid='6pjoBrrz4f1EzQMO'), Record(uid='a6Zf73YeFR7o7RFU'), Record(uid='fNBzuANAusnkFv2p'), Schema(uid='JfgNiPmWNLZz4YRh'), Feature(uid='pNaJLQh8fRA6'), Project(uid='BZF49Wr2yZAC')
Artifact(uid='9K1dteZ6Qx0EXK8g0000', version_tag=None, is_latest=True, key='example_datasets/mini_immuno/dataset1.h5ad', description='Flow cytometry readouts on invitro cell culture', suffix='.h5ad', kind='dataset', otype='AnnData', size=31672, hash='FB3CeMjmg1ivN6HDy6wsSg', n_files=None, n_observations=3, branch_id=1, created_on_id=1, space_id=1, storage_id=2, run_id=2, schema_id=1, created_by_id=1, created_at=2025-07-29 12:27:25 UTC, is_locked=False)
The artifact is now annotated.
artifact.describe()
Show code cell output
Artifact: example_datasets/mini_immuno/dataset1.h5ad (0000) | description: Flow cytometry readouts on invitro cell culture ├── uid: 9K1dteZ6Qx0EXK8g0000 run: VpiTmji (__lamindb_transfer__/4XIuR0tvaiXM) │ kind: dataset otype: AnnData │ hash: FB3CeMjmg1ivN6HDy6wsSg size: 30.9 KB │ branch: main space: all │ created_at: 2025-07-29 12:27:25 UTC created_by: anonymous │ n_observations: 3 ├── storage/path: s3://lamindata/.lamindb/9K1dteZ6Qx0EXK8g0000.h5ad ├── Dataset features │ ├── obs (8) │ │ assay_oid bionty.ExperimentalFactor.ontology… EFO:0008913 │ │ cell_type_by_expert bionty.CellType CD8-positive, alpha-beta T cell │ │ cell_type_by_model bionty.CellType B cell, T cell │ │ concentration str │ │ donor str │ │ perturbation ULabel DMSO, IFNG │ │ sample_note str │ │ treatment_time_h num │ └── var.T (3 bionty.Gene) │ CD14 num │ CD4 num │ CD8A num ├── External features │ └── experiment Record[scRNA-seq] EXP-scRNA-002 │ experiment ULabel Experiment 1 └── Labels └── .ulabels ULabel DMSO, IFNG, Experiment 1 .records Record EXP-scRNA-002 .projects Project Tutorials .cell_types bionty.CellType B cell, T cell, CD8-positive, alpha-be… .experimental_factors bionty.ExperimentalFactor single-cell RNA sequencing
# test the last 3 cells here
assert artifact.transform.description == "Transfer from `laminlabs/lamindata`"
assert artifact.transform.key == "__lamindb_transfer__/4XIuR0tvaiXM"
assert artifact.transform.uid == "4XIuR0tvaiXM0000"
assert artifact.run.initiated_by_run.transform.description.startswith("Transfer data")