Вопрос или проблема
Я хотел бы получить историю заказов для 25 тысяч клиентов. У меня есть адреса электронной почты каждого клиента. Мой текущий подход заключается в том, чтобы пройтись по адресам электронной почты, получить соответствующего клиента, а затем получить заказы, соответствующие этому клиенту.
Я хотел бы ускорить этот процесс с помощью одного или обоих из следующих методов:
1) Получение клиентов по адресам электронной почты партиями, а не по одному за раз.
2) Прямой переход от электронной почты клиента к списку заказов.
Как можно реализовать один из этих методов? Есть ли лучший способ достичь моей цели, который я упускаю из виду?
Редактировать: Мой текущий (работающий, но медленный) код:
import json
from woocommerce import API
with open("credentials/woocommerce_api_keys.json",'r') as f:
woo_credentials = json.load(f)
wcapi = API(
url="https://monq.com",
consumer_key=woo_credentials["consumer_key"],
consumer_secret=woo_credentials["consumer_secret"],
version="wc/v3"
)
with open("customer_emails.csv",'r') as f:
customer_emails = f.read().split(",")
customers = []
orders_by_customer = {}
order_dates_by_customer = {}
for email in customer_emails:
customer = wcapi.get("customers/?email={}".format(email)).json()
if len(customer) == 1:
customer = customer[0]
customers.append(customer)
customer_id = customer["id"]
orders = wcapi.get("orders/?customer={}".format(customer_id)).json()
orders_by_customer[email] = orders
order_dates = []
for o in orders:
order_dates.append(o["date_modified_gmt"])
order_dates_by_customer[email] = order_dates
else:
print("email {} возвращает {} клиентов".format(email,len(customer)))
with open("data/customers.json",'w') as f:
json.dump(customers,f,indent=4)
with open("data/orders_by_customer.json",'w') as f:
json.dump(orders_by_customer,f,indent=4)
with open("data/order_dates_by_customer.json","w") as f:
json.dump(order_dates_by_customer,f,indent=4)
Вам нужно реализовать цикл для всех электронных адресов, которые у вас есть в базе данных. Затем для каждого можно использовать следующий код:
$exists = email_exists($email);
if ( $exists )
echo "Этот E-mail зарегистрирован на номер пользователя ";
else
echo "Этот E-mail не принадлежит ни одному зарегистрированному пользователю на этом сайте";
Если у вас возникли проблемы, пожалуйста, поделитесь более подробной информацией о вашем вопросе.
Ответ или решение
Чтобы ускорить процесс получения истории заказов для 25 тысяч клиентов на основе их адресов электронной почты, вы можете рассмотреть два основных подхода:
1. Пакетный запрос для получения данных о клиентах
Вместо того чтобы обрабатывать каждого клиента по отдельности, вы можете группировать адреса электронной почты и делать запросы в пакетном режиме. Это не только сократит общее время выполнения, но и уменьшит количество запросов к API, что, в свою очередь, может снизить нагрузку и избежать ограничения по количеству запросов.
Реализация пакетного запроса
Предположим, ваш API поддерживает такие запросы. Вам нужно будет изменить ваш код, чтобы использовать подход с пакетными запросами. На примере вашего текущего кода это может выглядеть следующим образом:
import json
from woocommerce import API
with open("credentials/woocommerce_api_keys.json",'r') as f:
woo_credentials = json.load(f)
wcapi = API(
url="https://monq.com",
consumer_key=woo_credentials["consumer_key"],
consumer_secret=woo_credentials["consumer_secret"],
version="wc/v3"
)
def fetch_customers(emails):
email_param = ','.join(emails)
return wcapi.get(f"customers/?email={email_param}").json()
with open("customer_emails.csv",'r') as f:
customer_emails = f.read().split(",")
customers = []
orders_by_customer = {}
order_dates_by_customer = {}
# Обрабатываем электронные почты пакетами
batch_size = 100 # количество EMAIL'ов в одном запросе
for i in range(0, len(customer_emails), batch_size):
batch_emails = customer_emails[i:i + batch_size]
customer_data = fetch_customers(batch_emails)
for customer in customer_data:
customers.append(customer)
customer_id = customer["id"]
orders = wcapi.get(f"orders/?customer={customer_id}").json()
orders_by_customer[customer["email"]] = orders
order_dates = [o["date_modified_gmt"] for o in orders]
order_dates_by_customer[customer["email"]] = order_dates
with open("data/customers.json",'w') as f:
json.dump(customers, f, indent=4)
with open("data/orders_by_customer.json",'w') as f:
json.dump(orders_by_customer, f, indent=4)
with open("data/order_dates_by_customer.json","w") as f:
json.dump(order_dates_by_customer, f, indent=4)
2. Прямой переход от электронной почты к списку заказов
Если ваш API позволяет такой функционал, то можно сделать запрос на получение заказов непосредственно по адресу электронной почты. Это сократит количество необходимых запросов, поскольку вам не придется сначала извлекать информацию о клиентах.
Реализация прямого доступа к заказам
Проверьте, можно ли в вашем API использовать адрес электронной почты для получения информации о заказах. Если да, то ваш код может выглядеть так:
def fetch_orders_by_email(email):
# Проверьте, можно ли по email получить заказы напрямую в вашем API
return wcapi.get(f"orders/?search={email}").json()
# Основной цикл для получения заказов
for email in customer_emails:
orders = fetch_orders_by_email(email)
if orders:
orders_by_customer[email] = orders
order_dates = [o["date_modified_gmt"] for o in orders]
order_dates_by_customer[email] = order_dates
else:
print(f"No orders found for {email}")
Заключение
Ваша текущая настройка работает, но, как вы видите, вы можете значительно улучшить производительность, оптимизируя запросы. Использование пакетных запросов и прямой доступ к заказам через адрес электронной почты — ключевые шаги к ускорению процесса.
Подумайте также о том, чтобы задействовать обработку в многопоточном режиме, если API это позволяет, что дополнительно улучшит скорость выполнения вашего скрипта.