You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify GraphQL批量图片上传遇字符串格式化KeyError求助

Shopify GraphQL API批量上传图片触发KeyError问题排查与解决

问题描述

我正在尝试通过Shopify GraphQL API实现约2000张图片的自动化批量上传,需基于SKU/ProductID匹配确保图片对应正确商品。此前REST API版本可正常运行,但改用GraphQL提升效率后,多次调整请求格式仍触发KeyError错误。我是GraphQL和Shopify新手,附上相关代码及错误栈,请求定位问题。

代码示例

import shopify
import base64
import os

# 初始化Shopify客户端
shopify.ShopifyResource.set_site("https://your-shop-name.myshopify.com/admin/api/2024-07")
shopify.ShopifyResource.set_oauth_credentials(api_key="your-api-key", secret="your-secret")

def upload_product_image(product_id, image_path):
    query = '''
    mutation productImageCreate($input: ProductImageInput!) {
        productImageCreate(input: $input) {
            product {
                id
                title
            }
            userErrors {
                field
                message
            }
        }
    }
    '''
    with open(image_path, 'rb') as img_file:
        image_data = img_file.read()
    variables = {
        "input": {
            "productId": product_id,
            "image": {
                "src": f"data:image/jpeg;base64,{base64.b64encode(image_data).decode('utf-8')}"
            }
        }
    }
    response = shopify.GraphQL().execute(query, variables=variables)
    # 错误触发位置
    return response['data']['productImageCreate']['product']

# 批量处理逻辑(假设image_sku_map为SKU与图片路径的映射字典)
for sku, image_path in image_sku_map.items():
    product = shopify.Product.find(sku=sku)
    if product:
        upload_product_image(product.id, image_path)

错误栈

KeyError                                  Traceback (most recent call last)
<ipython-input-12-abc123> in <module>
     28     product = shopify.Product.find(sku=sku)
     29     if product:
---> 30         upload_product_image(product.id, image_path)

<ipython-input-12-abc123> in upload_product_image(product_id, image_path)
     22     response = shopify.GraphQL().execute(query, variables=variables)
     23     # 错误触发位置
---> 24     return response['data']['productImageCreate']['product']

KeyError: 'productImageCreate'

排查与解决步骤

1. 先处理响应中的错误信息

Shopify GraphQL API如果请求存在问题,data字段下不会返回productImageCreate,而是会在userErrors中返回错误详情。需要先判断响应结构:

def upload_product_image(product_id, image_path):
    # ... 原有查询与变量代码 ...
    response = shopify.GraphQL().execute(query, variables=variables)
    response_data = response.get('data', {})
    
    # 先检查是否存在错误
    mutation_result = response_data.get('productImageCreate', {})
    if 'userErrors' in mutation_result and mutation_result['userErrors']:
        for error in mutation_result['userErrors']:
            print(f"上传图片到商品 {product_id} 失败: {error['message']} (字段: {error['field']})")
        return None
    
    # 安全获取返回的商品信息
    product = mutation_result.get('product')
    if not product:
        print(f"商品 {product_id} 未返回有效数据")
        return None
    return product

2. 修正ProductID格式

GraphQL要求使用全局ID格式(gid://shopify/Product/[数字ID]),而非REST API返回的纯数字ID。需转换ID格式:

# 在批量处理逻辑中替换ID格式
for sku, image_path in image_sku_map.items():
    product = shopify.Product.find(sku=sku)
    if product:
        # 转换为GraphQL兼容的全局ID
        graphql_product_id = f"gid://shopify/Product/{product.id}"
        upload_product_image(graphql_product_id, image_path)

3. 验证图片Base64编码

确保图片编码完整且格式正确,可单独测试单张图片的编码是否能被Shopify识别:

# 测试编码是否正常
with open(image_path, 'rb') as img_file:
    image_data = img_file.read()
base64_str = base64.b64encode(image_data).decode('utf-8')
# 检查编码长度是否合理,避免空值或截断
print(f"图片编码长度: {len(base64_str)}")

4. 处理速率限制

Shopify GraphQL API默认限制每分钟1000次查询,批量上传2000张图片需添加重试机制避免429错误:

import time

def upload_product_image(product_id, image_path):
    # ... 原有查询与变量代码 ...
    try:
        response = shopify.GraphQL().execute(query, variables=variables)
    except shopify.exceptions.HttpError as e:
        if e.response.status_code == 429:
            retry_after = int(e.response.headers.get('Retry-After', 10))
            print(f"触发速率限制,{retry_after}秒后重试...")
            time.sleep(retry_after)
            return upload_product_image(product_id, image_path)
        else:
            raise
    # ... 后续响应处理代码 ...

内容的提问来源于stack exchange,提问作者Bobby Pope

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:55:18