如何从Google BigQuery行迭代器对象返回字符串?

时间:2019-08-28 14:26:25

标签: python-3.x google-bigquery

我的任务是编写一个Python脚本,该脚本可以获取BigQuery的结果并将其通过电子邮件发送出去。我已经编写了可以成功发送电子邮件的代码,但是在实际电子邮件中包含BigQuery脚本的结果时遇到了麻烦。查询结果是正确的,但是我从查询返回的实际对象(结果)始终以Nonetype返回。

例如,电子邮件应如下所示:

你好,

您有以下已“打开”超过7天的问题:

-在这里从bigquery代码中列出问题

谢谢。

该代码从contact.txt文件中读取联系人,并从message.txt文件中读取电子邮件模板。我试图将bigquery对象制成字符串,但是仍然会导致错误。

from google.cloud import bigquery
import warnings
warnings.filterwarnings("ignore", "Your application has authenticated using end user credentials")
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from string import Template


def query_emailtest():
    client = bigquery.Client(project=("analytics-merch-svcs-thd"))
    query_job = client.query("""
       select dept, project_name, reset, tier, project_status, IssueStatus, division, store_number, top_category,
       DATE_DIFF(CURRENT_DATE(), in_review, DAY) as days_in_review
       from `analytics-merch-svcs-thd.MPC.RESET_DETAILS`
       where in_review IS NOT NULL
       AND IssueStatus = "In Review"
       AND DATE_DIFF(CURRENT_DATE(), in_review, DAY) > 7
       AND ready_for_execution IS NULL
       AND project_status = "Active"
       AND program_name <> "Capital" 
       AND program_name <> "SSI - Capital"
       LIMIT 50
    """)
    results = query_job.result()  # Waits for job to complete. 
    return results #THIS IS A NONETYPE


def get_queryresults(results):   #created new method to put query results into a for loop and store it in a variable
    for i,row in enumerate(results,1):
        bq_data = (i , '. ' + str(row.dept) + " " + row.project_name + ", Reset #: " + str(row.reset) + ", Store #: " + str(row.store_number) + ", " + row.IssueStatus + " for " + str(row.days_in_review)+ " days")
        print (bq_data)

def get_contacts(filename):
    names = []
    emails = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        for a_contact in contacts_file:
            names.append(a_contact.split()[0])
            emails.append(a_contact.split()[1])
    return names, emails

def read_template(filename):
    with open(filename, 'r', encoding='utf-8') as template_file:
        template_file_content = template_file.read()
    return Template(template_file_content)


names, emails = get_contacts('mycontacts.txt')  # read contacts
message_template = read_template('message.txt')
results = query_emailtest()

bq_results = get_queryresults(query_emailtest())


import smtplib
# set up the SMTP server
s = smtplib.SMTP(host='smtp-mail.outlook.com', port=587)
s.starttls()
s.login('email', 'password')


   # For each contact, send the email:
for name, email in zip(names, emails):
    msg = MIMEMultipart()       # create a message

   # bq_data = get_queryresults(query_emailtest()) 

    # add in the actual person name to the message template
    message = message_template.substitute(PERSON_NAME=name.title())
    message = message_template.substitute(QUERY_RESULTS=bq_results) #SUBSTITUTE QUERY RESULTS IN MESSAGE TEMPLATE. This is where I am having trouble because the Row Iterator object results in Nonetype. 


    # setup the parameters of the message
    msg['From']='email'
    msg['To']='email'
    msg['Subject']="This is TEST"
  #  body = str(get_queryresults(query_emailtest())) #get query results from method to put into message body 


    # add in the message body
   # body = MIMEText(body)
    #msg.attach(body)
    msg.attach(MIMEText(message, 'plain'))


  #  query_emailtest() 
  #  get_queryresults(query_emailtest())


    # send the message via the server set up earlier.
    s.send_message(msg)

    del msg 

消息模板:

尊敬的$ {PERSON_NAME},

希望您一切都好。对于已被“审核中”超过7天的问题,请找到以下警报。

$ {QUERY_RESULTS}

如果您想了解更多信息,请访问此链接,其中包含警报的完整仪表板视图。

ISE服务

1 个答案:

答案 0 :(得分:2)

BQ result()函数返回一个生成器,所以我认为您需要将return更改为yield from

我距离python专家还很远,但是下面的简化代码对我有用。

from google.cloud import bigquery
import warnings
warnings.filterwarnings("ignore", "Your application has authenticated using end user credentials")

def query_emailtest():
    client = bigquery.Client(project=("my_project"))
    query_job = client.query("""
       select field1, field2 from `my_dataset.my_table` limit 5
    """)
    results = query_job.result()  
    yield from results # NOTE THE CHANGE HERE

results = query_emailtest()

for row in results:
    print(row.field1, row.field2)