Copying data to another table and auto-linking - how?

Hi everybody

Your Setup:

  • SeaTable Cloud

Describe the Problem/Error/Question:

I’m trying to transfer data from table A to table B.
I’m using Seatable’s automation for this.

However, in my A source data, I have a field of type “Link to another table”. The value must be transferred to table B.
I saw that the basic automation didn’t allow this, so I tried to make the modification in parallel, with a Python script.
Unable to write the answer, my script runs, retrieves the source value, but does not write it to destination B.

I wondered if it would be easier with a “Select” field, but I still have 50 values, and in any case, Seatable’s automation doesn’t do a simple transfer for this field either.

Python code :

from seatable_api import Base, context

# -------------------------------------
# Project-specific parameters
# -------------------------------------
TABLE_SOURCE = '1 - Liens élus'                       # Source table
TABLE_TARGET = 'Déclarants'                           # Target table
FIELD_LINK_SOURCE = 'Membres Mouvement Associatif'    # Link field in the source
FIELD_LINK_TARGET = 'Membre du mouvement associatif'  # Link field in the target
FIELD_ID = 'Courriel'                                 # Matching key (email)

# -------------------------------------
# Connect to SeaTable
# -------------------------------------
base = Base(context.api_token, context.server_url)
base.auth()

print("🔗 Starting the script: copying associative member links to target table...")

# -------------------------------------
# 1. Fetch all rows from source and target tables
# -------------------------------------
rows_source = base.list_rows(TABLE_SOURCE)
rows_target = base.list_rows(TABLE_TARGET)

# -------------------------------------
# 2. Build an index of target rows by email
# -------------------------------------
index_target = {
    row[FIELD_ID].strip().lower(): row
    for row in rows_target if FIELD_ID in row and row[FIELD_ID]
}

# -------------------------------------
# 3. Iterate through source rows and copy link values
# -------------------------------------
for row in rows_source:
    email = row.get(FIELD_ID, '').strip().lower()
    if not email:
        print(f"⚠️ Skipping row without email in {TABLE_SOURCE}.")
        continue

    if email not in index_target:
        print(f"❗ Email {email} not found in {TABLE_TARGET}.")
        continue

    target_row = index_target[email]
    row_id_target = target_row['_id']

    # Get the value from the link field in the source row
    link_value = row.get(FIELD_LINK_SOURCE)
    if not link_value:
        print(f"ℹ️  No associative member to copy for {email}.")
        continue

    # Extract row_ids from the link field (handles both dict and string cases)
    if isinstance(link_value, list):
        link_row_ids = [
            lv['row_id'] if isinstance(lv, dict) and 'row_id' in lv else lv
            for lv in link_value
        ]
    else:
        link_row_ids = [link_value]

    print(f"→ Copying member links {link_row_ids} to {email}")

    # Update the link field in the target row
    try:
        base.update_row(
            TABLE_TARGET,
            row_id_target,
            {FIELD_LINK_TARGET: link_row_ids}
        )
        print(f"✅ Member link(s) copied for {email}")
    except Exception as e:
        print(f"❌ Error updating member link(s) for {email} ({row_id_target}): {e}")

print("🏁 Script finished.")

Table structure

--- COMPLETE BASE STRUCTURE WITH ALL BASES AND COLUMNS ---
.
Table: 1 - Liens élus (ID: 5a06)
--> id (auto-number)
--> Courriel (email)
--> Élus (link --> QN9U)
--> Autre élu (text)
--> Premier dépôt (single-select)
--> Téléphone Parlementaire (text)
--> Niveau de relation (rate)
--> Fréquence des échanges (single-select)
--> Qualité de la relation (single-select)
--> Qualité de la relation Autre (text)
--> Intérêt pour le sujet associatif (rate)
--> Commentaires (long-text)
--> Prénom du déclarant (text)
--> Nom du déclarant (text)
--> Fonction dans l'association (text)
--> Nom de l'association (text)
--> Téléphone (text)
--> Association membre Fédération ou réseau (single-select)
--> Membres Mouvement Associatif (link --> FtYW)
--> Participation plaidoyer (single-select)
--> Date de dépôt (date)
--> Adresse Association (text)
--> Code postal Association (number)
--> Ville Association (text)
--> Test julien (single-select)
.
Table: 2 - Interactions élus (ID: X3wU)
--> id (auto-number)
--> Courriel (email)
--> Courriel normifié (formula)
--> Élu (link --> QN9U)
--> Autre élu (text)
--> Premier dépôt (single-select)
--> Téléphone Parlementaire (text)
--> Prénom du déclarant (text)
--> Nom du déclarant (text)
--> Fonction dans l'association (text)
--> Nom de l'association (text)
--> Téléphone (text)
--> Association membre Fédération ou réseau (single-select)
--> Membres Mouvement Associatif (link --> FtYW)
--> Participation plaidoyer (single-select)
--> Type d'échange (single-select)
--> Type d'échange Autre (text)
--> Date (date)
--> Sujet (multiple-select)
--> Sujet Autre (text)
--> Position exprimée (single-select)
--> Commentaires (long-text)
--> Adresse Association (text)
--> Code postal Association (number)
--> Ville Association (text)
--> Date de dépôt (date)
.
Table: Déclarants (ID: Qi9U)
--> Numéro (auto-number)
--> Courriel (email)
--> Prénom du déclarant (text)
--> Nom du déclarant (text)
--> Fonction dans l'association (text)
--> Nom de l'association (text)
--> Téléphone (text)
--> Association membre Fédération ou réseau (single-select)
--> Membre du mouvement associatif (link --> FtYW)
--> Participation plaidoyer (single-select)
--> Date de dépôt (date)
--> Adresse Association (text)
--> Code postal Association (number)
--> Ville Association (text)
--> Département Association (text)
--> Région Association (text)
--> Coordonnées GPS Association (geolocation)
--> Date de création (date)
.
Table: Élus (ID: QN9U)
--> Nom complet (formula)
--> Fonction (multiple-select)
--> Libellé de la région (text)
--> Code du département (number)
--> Libellé du département (text)
--> Libellé de la section départementale (text)
--> Libellé du secteur (text)
--> Code du canton (number)
--> Code de la commune (text)
--> Libellé du canton (text)
--> Prénom de l'élu (text)
--> Nom de l'élu (text)
--> Code sexe (single-select)
--> Date de naissance (date)
--> Code de la catégorie socio-professionnelle (number)
--> Libellé de la catégorie socio-professionnelle (text)
--> Libellé de la fonction (text)
--> Date de début du mandat (date)
--> Date de début de la fonction (date)
--> Date d'importation (date)
--> Typologie (single-select)
--> hash_key (text)
--> Lieu de naissance (text)
--> Code de la collectivité à statut particulier (text)
--> Libellé de la collectivité à statut particulier (text)
--> Code de la circonscription législative (text)
--> Libellé de la circonscription législative (text)
--> Libellé de la commune (text)
--> Code nationalité (text)
--> 1 - Liens élus (link --> 5a06)
--> En activité (checkbox)
--> Date de fin de la fonction (date)
--> Gouvernement (text)
--> Fonction au gouvernement (text)
--> Date de fin du mandat (text)
--> 2 - Interactions élus (link --> X3wU)
.
Table: Membres MA (ID: FtYW)
--> Nom (text)
--> Territoire (text)
--> Membre actif (checkbox)
--> 1 - Liens élus (link --> 5a06)
--> 2 - Interactions élus (link --> X3wU)
--> Déclarants (link --> Qi9U)

Does anyone know if there’s a way to transfer this data?

Thank you very much,
Kind regards,
Julien.

I’d use a script for both:
1.) Copy the data from A to B
2.) Create the link to the new record in B to wherever

As for 1.) See Rows - SeaTable Developer Manual

As for 2.) See Links - SeaTable Developer Manual

Hi!

I wasn’t using the good function.
With “getLink” it works!

Thank you very much @rdb

My problem is solved

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.