Mises à jour à l'aide de masques de champ

Dans l'API Google Ads, les mises à jour sont effectuées à l'aide d'un masque de champ. Le masque de champ liste tous les champs que vous souhaitez modifier avec la mise à jour. Tous les champs spécifiés qui ne figurent pas dans le masque de champ sont ignorés, même s'ils sont envoyés au serveur.

Assistant de masque de champ

La méthode recommandée pour générer des masques de champ consiste à utiliser la fonction d'assistance field_mask incluse dans le package google.api_core. Il accepte deux objets protobuf et renvoie un objet de masque de champ avec une liste paths contenant tous les champs différents entre les deux objets.

Si None est transmis en tant que premier paramètre, la liste du masque de champ contient tous les champs du deuxième objet protobuf qui ne sont pas définis sur leur valeur par défaut.

Une fois construit, l'objet de masque de champ doit être copié sur l'objet d'opération qui sera envoyé au serveur.

Mettre à jour à partir d'un nouvel objet local

Dans l'exemple suivant, vous créez un objet CampaignOperation vide et récupérez un objet Campaign vide à partir de son champ update. Vous modifiez ensuite cet objet de campagne et créez un masque de champ en le comparant à None, ce qui génère un masque de champ contenant le champ network_settings.target_search_network modifié :

from google.ads.googleads.client import GoogleAdsClient
from google.api_core import protobuf_helpers

# Retrieve a GoogleAdsClient instance.
client = GoogleAdsClient.load_from_storage()

# Create a new campaign operation.
campaign_operation = client.get_type("CampaignOperation")

# Retrieve a new campaign object from its update field and set its resource
# name.
campaign = campaign_operation.update
campaign.resource_name = client.get_service("CampaignService").campaign_path(
    customer_id, campaign_id
)

# Mutate the campaign (use direct attribute assignment in proto-plus).
campaign.network_settings.target_search_network = False

# Create a field mask using the updated campaign.
# The field_mask helper is compatible with raw protobuf message instances,
# which you can access using the ._pb attribute.
field_mask = protobuf_helpers.field_mask(None, campaign._pb)

# Copy the field_mask onto the operation's update_mask field.
client.copy_from(campaign_operation.update_mask, field_mask)

Mettre à jour une ressource existante

L'exemple suivant met à jour une campagne existante récupérée à partir de l'API, en supposant que resource_name et customer_id sont valides. Avec cette stratégie, updated_campaign partage tous les champs récupérés sur initial_campaign (y compris son resource_name), et le masque de champ généré indique à l'API que seul le champ network_settings.target_search_network a été modifié :

from google.ads.googleads.client import GoogleAdsClient
from google.api_core import protobuf_helpers

# Retrieve a GoogleAdsClient instance.
client = GoogleAdsClient.load_from_storage()

# Retrieve an instance of the GoogleAdsService.
googleads_service = client.get_service("GoogleAdsService")

# Search query to retrieve the campaign. Quote string literals in GAQL.
query = f"""
    SELECT
      campaign.network_settings.target_search_network,
      campaign.resource_name
    FROM campaign
    WHERE campaign.resource_name = '{resource_name}'"""

# Submit a query to retrieve a campaign instance.
response = googleads_service.search_stream(
    customer_id=customer_id, query=query
)

# Iterate over results to retrieve the campaign.
initial_campaign = None
for batch in response:
    for row in batch.results:
        initial_campaign = row.campaign
        break

if not initial_campaign:
    raise ValueError(f"Campaign '{resource_name}' not found.")

# Create a new campaign operation.
campaign_operation = client.get_type("CampaignOperation")

# Set the copied campaign object to a variable for easy reference.
updated_campaign = campaign_operation.update

# Copy the retrieved campaign into the new campaign.
# client.copy_from works with both native protobuf messages and messages
# wrapped by the proto-plus library.
client.copy_from(updated_campaign, initial_campaign)

# Mutate the new campaign.
updated_campaign.network_settings.target_search_network = False

# Create a field mask by comparing initial and updated protobuf objects.
field_mask = protobuf_helpers.field_mask(
    initial_campaign._pb, updated_campaign._pb
)

# Copy the field mask onto the operation's update_mask field.
# Note that the client's copy_from method works with both native messages
# and messages wrapped by proto-plus, including google.protobuf.field_mask_pb2.
client.copy_from(campaign_operation.update_mask, field_mask)

Effacer les champs ou définir des messages vides

Lorsque vous effectuez une comparaison avec None, l'assistant field_mask ignore les champs définis sur des valeurs vides ou par défaut. Pour effacer explicitement un champ ou définir un champ de message vide, ajoutez le chemin d'accès au champ directement à campaign_operation.update_mask.paths. Pour en savoir plus, consultez Définir des objets de message vides en tant que champs.