From 0891b4845b294d8bc8476903d79c06a6e2c39d07 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Thu, 16 Jul 2026 07:51:22 -0700 Subject: [PATCH 1/6] deprecated migrate functions --- synapseutils/migrate_functions.py | 182 ++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/synapseutils/migrate_functions.py b/synapseutils/migrate_functions.py index 60e82586c..2b6efab75 100644 --- a/synapseutils/migrate_functions.py +++ b/synapseutils/migrate_functions.py @@ -8,6 +8,8 @@ import typing from enum import Enum +from deprecated import deprecated + import synapseclient from synapseclient.core import pool_provider, utils from synapseclient.core.constants import concrete_types @@ -25,7 +27,34 @@ """ +@deprecated( + version="4.14.0", + reason=( + "To be removed in 5.0.0. " + "Use synapseclient.core.utils.test_import_sqlite3 instead." + ), +) def test_import_sqlite3(): + """ + Verify that the sqlite3 module is importable, raising an ImportError with + an explanatory message if it is not. + + Example: Migration to the new location +   + + This function moved to synapseclient.core.utils. Update the import; the + behavior is unchanged. + + ```python + # Old approach (DEPRECATED) + # from synapseutils.migrate_functions import test_import_sqlite3 + + # New approach (RECOMMENDED) + from synapseclient.core.utils import test_import_sqlite3 + + test_import_sqlite3() + ``` + """ # sqlite3 is part of the Python standard library and is available on the vast majority # of Python installations and doesn't require any additional software on the system. # it may be unavailable in some rare cases though (for example Python compiled from source @@ -101,6 +130,13 @@ def _get_row_dict(cursor, row, include_empty): } +@deprecated( + version="4.14.0", + reason=( + "To be removed in 5.0.0. " + "Use the MigrationResult class from synapseclient.models.services instead." + ), +) class MigrationResult: """A MigrationResult is a proxy object to the underlying sqlite db. It provides a programmatic interface that allows the caller to iterate over the @@ -110,6 +146,48 @@ class MigrationResult: migrating a huge project of hundreds of thousands/millions of entities. As this proxy object is not thread safe since it accesses an underlying sqlite db. + + Example: Migration to the new class +   + + This class is replaced by the MigrationResult class in + synapseclient.models.services, which is returned by the new migration + methods on the Project and Folder models. The new class offers the same + methods plus async variants of each, and no longer requires a Synapse + object to be passed in. + + ```python + # Old approach (DEPRECATED) + # result returned by synapseutils.index_files_for_migration or + # synapseutils.migrate_indexed_files + # counts = result.get_counts_by_status() + # for migration in result.get_migrations(): + # print(migration) + # result.as_csv("/tmp/migration.csv") + + # New approach (RECOMMENDED) + from synapseclient import Synapse + from synapseclient.models import Project + + syn = Synapse() + syn.login() + + # The new MigrationResult is returned by the migration methods on the + # Project and Folder models + result = Project(id="syn123").index_files_for_migration( + dest_storage_location_id="12345", + ) + + # Inspect the counts of files by migration status + print(result.get_counts_by_status()) + + # Iterate over each file/version in the migration index + for migration in result.get_migrations(): + print(migration) + + # Write the contents of the migration index to a csv file + result.as_csv("/tmp/migration.csv") + ``` """ def __init__(self, syn, db_path): @@ -433,6 +511,16 @@ def _wait_futures(conn, cursor, futures, pending_keys, return_when, continue_on_ return futures, completed_file_handle_ids +@deprecated( + version="4.14.0", + reason=( + "To be removed in 5.0.0. " + "Use the index_files_for_migration method on the Project or Folder models " + "from synapseclient.models instead, or the " + "synapseclient.models.services.index_files_for_migration_async function " + "for File and Table entities." + ), +) def index_files_for_migration( syn: synapseclient.Synapse, entity, @@ -479,6 +567,48 @@ def index_files_for_migration( Returns: A MigrationResult object that can be used to inspect the contents of the index or output the index to a CSV for manual inspection. + + Example: Migration to the new approach +   + + Use the index_files_for_migration method on the Project or Folder models + from synapseclient.models instead. The new method is called on the model + instance, uses the logged in Synapse client automatically, and db_path is + optional (a temporary location is used if not provided and is available + on the returned MigrationResult as result.db_path). For File and Table + entities, use the index_files_for_migration_async function from + synapseclient.models.services. + + ```python + # Old approach (DEPRECATED) + # import synapseclient + # import synapseutils + # + # syn = synapseclient.login() + # result = synapseutils.index_files_for_migration( + # syn, + # "syn123", + # dest_storage_location_id="12345", + # db_path="/tmp/migration.db", + # file_version_strategy="new", + # ) + + # New approach (RECOMMENDED) + from synapseclient import Synapse + from synapseclient.models import Project + + syn = Synapse() + syn.login() + + project = Project(id="syn123") + result = project.index_files_for_migration( + dest_storage_location_id="12345", + db_path="/tmp/migration.db", + file_version_strategy="new", + ) + print(f"Indexed files stored in the database at: {result.db_path}") + print(f"Counts by status: {result.get_counts_by_status()}") + ``` """ # noqa root_id = utils.id_of(entity) @@ -598,6 +728,15 @@ def _check_file_handle_exists(cursor, from_file_handle_id): return row[0] if row else None +@deprecated( + version="4.14.0", + reason=( + "To be removed in 5.0.0. " + "Use the migrate_indexed_files method on the Project or Folder models " + "from synapseclient.models instead, or the " + "synapseclient.models.services.migrate_indexed_files_async function." + ), +) def migrate_indexed_files( syn: synapseclient.Synapse, db_path: str, @@ -623,6 +762,49 @@ def migrate_indexed_files( Returns: A MigrationResult object that can be used to inspect the results of the migration. + + Example: Migration to the new approach +   + + Use the migrate_indexed_files method on the Project or Folder models + from synapseclient.models instead. The new method is called on the model + instance and uses the logged in Synapse client automatically. For File + and Table entities, use the migrate_indexed_files_async function from + synapseclient.models.services. + + ```python + # Old approach (DEPRECATED) + # import synapseclient + # import synapseutils + # + # syn = synapseclient.login() + # result = synapseutils.migrate_indexed_files( + # syn, + # db_path="/tmp/migration.db", + # force=True, + # ) + + # New approach (RECOMMENDED) + from synapseclient import Synapse + from synapseclient.models import Project + + syn = Synapse() + syn.login() + + project = Project(id="syn123") + + # Index the files first + index_result = project.index_files_for_migration( + dest_storage_location_id="12345", + ) + + # Then migrate using the same database path + result = project.migrate_indexed_files( + db_path=index_result.db_path, + force=True, # Skip the interactive confirmation prompt + ) + print(f"Counts by status: {result.get_counts_by_status()}") + ``` """ executor, max_concurrent_file_copies = _get_executor(syn) From 0ae6409ffa9b7719504f9b5c179d21efd5cf8cf0 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Thu, 16 Jul 2026 07:55:50 -0700 Subject: [PATCH 2/6] simplified example --- synapseutils/migrate_functions.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/synapseutils/migrate_functions.py b/synapseutils/migrate_functions.py index 2b6efab75..16273f7ca 100644 --- a/synapseutils/migrate_functions.py +++ b/synapseutils/migrate_functions.py @@ -152,9 +152,7 @@ class MigrationResult: This class is replaced by the MigrationResult class in synapseclient.models.services, which is returned by the new migration - methods on the Project and Folder models. The new class offers the same - methods plus async variants of each, and no longer requires a Synapse - object to be passed in. + methods on the Project and Folder models. ```python # Old approach (DEPRECATED) @@ -163,7 +161,6 @@ class MigrationResult: # counts = result.get_counts_by_status() # for migration in result.get_migrations(): # print(migration) - # result.as_csv("/tmp/migration.csv") # New approach (RECOMMENDED) from synapseclient import Synapse @@ -180,13 +177,6 @@ class MigrationResult: # Inspect the counts of files by migration status print(result.get_counts_by_status()) - - # Iterate over each file/version in the migration index - for migration in result.get_migrations(): - print(migration) - - # Write the contents of the migration index to a csv file - result.as_csv("/tmp/migration.csv") ``` """ From faf30d3523ec2262070b5ce15f80797dc84b5248 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 22 Jul 2026 09:09:31 -0700 Subject: [PATCH 3/6] Update synapseutils/migrate_functions.py Co-authored-by: Dan Lu <90745557+danlu1@users.noreply.github.com> --- synapseutils/migrate_functions.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/synapseutils/migrate_functions.py b/synapseutils/migrate_functions.py index 16273f7ca..6d16b3036 100644 --- a/synapseutils/migrate_functions.py +++ b/synapseutils/migrate_functions.py @@ -176,7 +176,17 @@ class MigrationResult: ) # Inspect the counts of files by migration status - print(result.get_counts_by_status()) + project = Project(id="syn123").get() + index_result = my_migration_folder.index_files_for_migration( + dest_storage_location_id = "123456", + db_path="/path/to/your/migration.db", + include_table_files=False, # Set True if you also want table-attached files + ) + + index_result.as_csv("/path/to/your/index_results.csv") + print(f"Migration index database: {index_result.db_path}") + print(f"Indexed counts by status: {index_result.counts_by_status}") + ``` """ From 2fb2699070c7c965d66489b683646bdb833d77d8 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 22 Jul 2026 09:09:42 -0700 Subject: [PATCH 4/6] Update synapseutils/migrate_functions.py Co-authored-by: Dan Lu <90745557+danlu1@users.noreply.github.com> --- synapseutils/migrate_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapseutils/migrate_functions.py b/synapseutils/migrate_functions.py index 6d16b3036..1eb5a9fd3 100644 --- a/synapseutils/migrate_functions.py +++ b/synapseutils/migrate_functions.py @@ -600,7 +600,7 @@ def index_files_for_migration( syn = Synapse() syn.login() - project = Project(id="syn123") + project = Project(id="syn123").get() result = project.index_files_for_migration( dest_storage_location_id="12345", db_path="/tmp/migration.db", From 42900698486aedc5e25752c333ab8ea8aad6d932 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 22 Jul 2026 09:09:51 -0700 Subject: [PATCH 5/6] Update synapseutils/migrate_functions.py Co-authored-by: Dan Lu <90745557+danlu1@users.noreply.github.com> --- synapseutils/migrate_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapseutils/migrate_functions.py b/synapseutils/migrate_functions.py index 1eb5a9fd3..55a163b4c 100644 --- a/synapseutils/migrate_functions.py +++ b/synapseutils/migrate_functions.py @@ -791,7 +791,7 @@ def migrate_indexed_files( syn = Synapse() syn.login() - project = Project(id="syn123") + project = Project(id="syn123").get() # Index the files first index_result = project.index_files_for_migration( From 431e9d6a0bd5b0c3de2cb8e7d716a7784b8e9770 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Wed, 22 Jul 2026 09:08:52 -0700 Subject: [PATCH 6/6] change exampels from stirngs to ints --- synapseutils/migrate_functions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/synapseutils/migrate_functions.py b/synapseutils/migrate_functions.py index 55a163b4c..612a06549 100644 --- a/synapseutils/migrate_functions.py +++ b/synapseutils/migrate_functions.py @@ -172,7 +172,7 @@ class MigrationResult: # The new MigrationResult is returned by the migration methods on the # Project and Folder models result = Project(id="syn123").index_files_for_migration( - dest_storage_location_id="12345", + dest_storage_location_id=12345, ) # Inspect the counts of files by migration status @@ -602,7 +602,7 @@ def index_files_for_migration( project = Project(id="syn123").get() result = project.index_files_for_migration( - dest_storage_location_id="12345", + dest_storage_location_id=12345, db_path="/tmp/migration.db", file_version_strategy="new", ) @@ -795,7 +795,7 @@ def migrate_indexed_files( # Index the files first index_result = project.index_files_for_migration( - dest_storage_location_id="12345", + dest_storage_location_id=12345, ) # Then migrate using the same database path