views:

49

answers:

3

I have a python script which reads email addresses from a database for a particular date, example today, and sends out an email message to them one by one. It reads data from MySQL using the MySQLdb module and stores all results in a dictionary and sends out emails using :

rows = cursor.fetchall () #All email addresses returned that are supposed to go out on todays date.

for row is rows: #send email

However, my hosting service only lets me send out 500 emails per hour. How can I limit my script from making sure only 500 emails are sent in an hour and then to check the database if more emails are left for today or not and then to send them in the next hour.

The script is activated using a cron job.

A: 

When you send an email, do you record it in the database in some way so that the same email address wouldn't be returned by another query in the same day? (say, by removing the email address, or setting a flag, or something?) If so, you could just add a LIMIT 500 to your SQL query and run the Python script every hour.

David Zaslavsky
As I just found out about the limit, my script so far was simply designed to return all email addresses for todays date and delete all of them after sending out the emails. and the cron job ran the script only once per day. SELECT * FROM mytable WHERE Date =('%s') """ % (date)) so I suppose, I should add LIMIT 500 at the end for the retrieval. But what about the deleting? How do I ensure only the 500 sent are deleted? I can have the crob job run every every hour.DELETE * FROM table_name WHERE date= todays_date LIMIT 500 ?
Ali
@Ali, this would be dangerous. Here is what I would suggest.Have two more columns 'id' (primary key) and 'is_sent' (bool). Default value of is_sent is false. When the email for one particular email address is sent successfully, the is_sent flag for the particular id can be set to true. This way you can accurately delete the sent emails, and the ones that could not get sent can be tried again.
nano
A: 

I would have the script run hourly using cron and limit the number of records that you take from the database to about 490 (just to be on the safe side) by using fetchmany instead of fetchall.

icio
+3  A: 

If you don't mind if the script is running for hours on end, you can just pause for a few seconds between each email.

from time import sleep

if address_count < 500:
    sleep_time = 0
else:
    sleep_time = 7.5

for address in addresses:
    send_message(address)
    sleep(sleep_time)

(Note: This was written for maximum clarity, not maximum efficiency)

Josh Wright
I cant run the script for hours on end as it will use up CPU cycles. The cron job does it well enough. My problem is now just deleting the 500 0r 490 emails I have already sent from the mysql database.
Ali
sleep() doesn't eat up CPU time.
Josh Wright