Пример из реального мира
Предположим, у вас есть 100 миллионов доменов в таблице MySQL, и вы хотите обновить Alexa рейтинг для каждого домена.
Первое, что вам нужно, это выбрать доменные имена из базы данных.
Допустим, имя вашей таблицы domains
, а имя столбца domain
.
Если вы используете SELECT domain FROM domains
, он вернет 100 миллионов строк, которые будут занимать много памяти. Таким образом, ваш сервер может произойти сбой.
Итак, вы решили запустить программу партиями. Допустим, размер нашей партии равен 1000.
В нашем первом пакете мы запросим первые 1000 строк, проверим Alexa рейтинг для каждого домена и обновим строку базы данных.
В нашей второй партии мы будем работать над следующими 1000 строками. В нашей третьей партии это будет с 2001 по 3000 и т. Д.
Теперь нам нужна функция генератора, которая генерирует наши партии.
Вот наша функция генератора:
def ResultGenerator(cursor, batchsize=1000):
while True:
results = cursor.fetchmany(batchsize)
if not results:
break
for result in results:
yield result
Как видите, наша функция сохраняет yield
результатов. Если вы используете ключевое слово return
вместо yield
, вся функция будет завершена, как только она достигнет возврата.
return - returns only once
yield - returns multiple times
Если функция использует ключевое слово yield
, то это генератор.
Теперь вы можете выполнять итерации следующим образом:
db = MySQLdb.connect(host="localhost", user="root", passwd="root", db="domains")
cursor = db.cursor()
cursor.execute("SELECT domain FROM domains")
for result in ResultGenerator(cursor):
doSomethingWith(result)
db.close()