Search code examples
pythonsmtpsqlalchemysmtplibpython-elixir

Using python and elixir to send emails utilizing db tables with foreign keys


I have a python script that pulls information from a single database table and sends a weekly update email to users. I'd like to find a way to modify my code to allow for normalizing the structure and putting all of the investigator info (prefix, fname, lname, and email) into it's own table. However, I'm not sure how to do this within the structure of the elixir model and my python code.

Here is my current elixir model file:

from elixir import *
import auth as auth
au = auth.UserAuth()

metadata.bind = 'mysql://' + au.user + ':' + au.password + '@localhost/' + au.database
metadata.bind.echo = True


class Protocol(Entity):
    id = Field(Integer, primary_key = True)
    irb_no = Field(Text)
    title = Field(Text)
    prefix = Field(Text)
    fname = Field(Text)
    lname = Field(Text)
    email = Field(Text)
    action_date = Field(Date)
    action = Field(Text)
    approved = Field(Integer)
    using_options(tablename = 'protocols')

    def __repr__ (self):
        return '%d' %(self.id)

And here is my python script:

import smtplib
import auth as auth
import ProtocolModel as PM
from elixir import *
from datetime import datetime

au = auth.UserAuth()
setup_all()
create_all()
table = PM.Protocol
records = table.query.all()

if len(records) == 0:
    print 'No records in Table'
else:
    for record in records:
        setup_all()
        if record.approved == 1:
            print 'Completed'
        else:
            FROMADDR = au.google_user
            LOGIN    = FROMADDR
            PASSWORD = au.google_password
            TOADDRS  = record.email
            SUBJECT  = "Weekly Research Update for " + record.irb_no + " - " + record.title
            date1 = datetime.strptime(str(record.action_date), '%Y-%m-%d')
            date2 = date1.strftime('%B %d, %Y')
            msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (FROMADDR, ", ".join(TOADDRS), SUBJECT) )
            msg += 'Dear' + ' ' + record.prefix + ' ' + record.fname + ' ' + record.lname + ',' + '\n' + '\n'
            msg += 'Our records indicate that the most recent action on your research protocol titled ' + record.title + ' was taken on ' + str(date2) +'.' +'\n'
            msg += 'This action was: ' + record.action

            server = smtplib.SMTP('smtp.gmail.com', 587)
            server.set_debuglevel(1)
            server.ehlo()
            server.starttls()
            server.login(LOGIN, PASSWORD)
            server.sendmail(FROMADDR, TOADDRS, msg)
            server.quit()

This seems like it should be a relatively simple change, but I'm just not sure how to go about this. Any help is much appreciated, thanks!


Solution

  • I figured it out. Used ManyToOne in the new entity class in the model file and referenced that in the python code. It was a simple fix once I got back into it.

    New elixir model:

    from elixir import *
    import auth as auth
    au = auth.UserAuth()
    
    metadata.bind = 'mysql://' + au.user + ':' + au.password + '@localhost/' + au.database
    metadata.bind.echo = True
    
    class Investigator(Entity):
        id = Field(Integer, primary_key = True)
        prefix = Field(Text)
        fname = Field(Text)
        lname = Field(Text)
        email = Field(Text)
        using_options(tablename = 'investigators')
    
        def __repr__ (self):
            return '%d' %(self.id)
    
    
    class Protocol(Entity):
        id = Field(Integer, primary_key = True)
        irb_no = Field(Text)
        title = Field(Text)
        investigator = ManyToOne('Investigator', colname='investigator_id')
        action_date = Field(Date)
        action = Field(Text)
        approved = Field(Integer)
        using_options(tablename = 'protocols')
    
        def __repr__ (self):
            return '%d' %(self.id)
    

    New python script:

    import smtplib
    import auth as auth
    import ProtocolModel1 as PM
    from elixir import *
    from datetime import datetime
    
    au = auth.UserAuth()
    setup_all()
    create_all()
    table = PM.Protocol
    records = table.query.all()
    
    if len(records) == 0:
        print 'No records in Table'
    else:
        for record in records:
            setup_all()
            if record.approved == 1:
                print 'Completed'
            else:
                FROMADDR = au.google_user
                LOGIN    = FROMADDR
                PASSWORD = au.google_password
                TOADDRS  = record.investigator.email
                SUBJECT  = "Weekly Research Update for " + record.irb_no + " - " + record.title
                date1 = datetime.strptime(str(record.action_date), '%Y-%m-%d')
                date2 = date1.strftime('%B %d, %Y')
                msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (FROMADDR, ", ".join(TOADDRS), SUBJECT) )
                msg += 'Dear' + ' ' + record.investigator.prefix + ' ' + record.investigator.fname + ' ' + record.investigator.lname + ',' + '\n' + '\n'
                msg += 'Our records indicate that the most recent action on your research protocol titled ' + record.title + ' was taken on ' + str(date2) +'.' +'\n'
                msg += 'This action was: ' + record.action
    
                server = smtplib.SMTP('smtp.gmail.com', 587)
                server.set_debuglevel(1)
                server.ehlo()
                server.starttls()
                server.login(LOGIN, PASSWORD)
                server.sendmail(FROMADDR, TOADDRS, msg)
                server.quit()