#python-3.x #postgresql #recursion #python-requests #psycopg2
#python-3.x #postgresql #рекурсия #python-запросы #psycopg2
Вопрос:
Мне нужно загрузить 400 тыс. записей через API и сохранить их локально в БД. Каждый запрос возвращает 500 записей курсор для следующей страницы. Я использую рекурсию и вижу, что python3
каждый процесс рекурсии потребляет больше оперативной памяти (около 50 МБ на рекурсию, поэтому мне нужно иметь 40 ГБ оперативной памяти для загрузки всего). Каков способ очистки оперативной памяти после каждой рекурсии?
import os
import psycopg2
import requests
from psycopg2.extras import execute_values
class SomeClass:
def __init__:
with psycopg2.connect(
host='localhost',
dbname=os.getenv("POSTGRES_DBNAME"),
user=os.getenv("POSTGRES_USER"),
password=os.getenv("POSTGRES_PASSWORD")
) as self.conn:
self.products_download_n_save()
def products_download_n_save(self, cursor=''):
basic_url = 'SOME_URL'
if not cursor:
url = basic_url
else:
url = f'{basic_url}?cursor={cursor}'
r = requests.get(url)
response = r.json()
products = response['products']
# Need to loop every product, because different product have different amount of fields
for product_d in products:
values = [[value for value in product_d.values()]]
columns = product_d.keys()
do_update_query = ','.join([f'{column} = excluded.{column}' for column in columns])
query = f"INSERT INTO {self.PRODUCTS_TABLE_NAME} ({','.join(columns)}) VALUES %s "
f"on conflict(productCode) "
f"DO UPDATE SET {do_update_query};"
with self.conn.cursor() as cursor:
execute_values(cursor, query, values)
self.conn.commit()
response_cursor = response.get('nextCursor', '')
if response_cursor:
self.products_download_n_save(response_cursor)
Ответ №1:
Найдено решение — переместить код из рекурсии в while response_cursor
цикл.