BigQuery For Loop Результаты в тело сообщения Python smtplib

Я хочу получать данные из базы данных BigQuery с заданным интервалом и автоматически отправлять результаты по электронной почте с помощью smtplib.

У меня есть пример ниже. Я могу запросто получить данные из BigQuery. Я могу отправить электронную почту через smtplib просто отлично. Что мне нужно сделать, это объединить. Я хочу сохранить результаты цикла for в теле сообщения электронной почты. Я считаю, что делаю это, вызывая функцию. Однако когда я это делаю. Я получаю ошибку.

Файл "bqtest5.py", строка 52, в server.sendmail(имя_логина, получатели, query_named_params('corpus', 'min_word_count')) Файл "/usr/lib/python2.7/smtplib.py", строка 729, в sendmail esmtp_opts.append("size=%d" % len(msg)) TypeError: объект типа 'NoneType' не имеет len()

from google.cloud import bigquery
import smtplib

#Variables
login_email = 'MYEMAIL'
login_pwd = 'MYPASSWORD'
recipients ='EMAILSENDINGTO'


#Create a function
#specifies we are going to add two paramaters
def query_named_params(corpus, min_word_count):
    #Create a Client
    client = bigquery.Client()
    #Define the query
    query = """
        SELECT word, word_count
        FROM `bigquery-public-data.samples.shakespeare`
        WHERE corpus = @corpus
        AND word_count >= @min_word_count
        ORDER BY word_count DESC;
        """
    #Define the paramaters
    query_params = [
        bigquery.ScalarQueryParameter('corpus', 'STRING', 'sonnets'),
        bigquery.ScalarQueryParameter(
            'min_word_count', 'INT64', 10)
    ]
    #Create job configuration
    job_config = bigquery.QueryJobConfig()
    #Add Query paramaters
    job_config.query_parameters = query_params
    #P
    query_job = client.query(query, job_config=job_config)

    # Print the results.
    destination_table_ref = query_job.destination
    table = client.get_table(destination_table_ref)
    resulters = client.list_rows(table)
    for row in resulters:
        print("{} : {} views".format(row.word, row.word_count))

# --------------------EMAIL PORTION -------------#
#)smtplib connection    print('messenger()')
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(login_email, login_pwd)

msg = """

"""
server.sendmail(login_email, recipients, query_named_params('corpus', 
'min_word_count'))
server.quit()


if __name__ == '__main__':
    query_named_params('corpus','min_word_count')

person Jeff    schedule 28.01.2018    source источник
comment
Заменить msg на messenger() ?   -  person match    schedule 28.01.2018
comment
Это дает мне ошибку Traceback (последний последний вызов): Файл bqtest4.py, строка 53, в ‹module› query_named_params('corpus','min_word_count') Файл bqtest4.py, строка 48, в query_named_params server.sendmail(login_email , получатели, messenger()) Файл /usr/lib/python2.7/smtplib.py, строка 729, в sendmail esmtp_opts.append(size=%d % len(msg)) TypeError: объект типа 'NoneType' не имеет len() Таким образом, функция возвращает None при вызове там, но возвращает результаты, если я просто печатаю их на странице. Не уверен, почему.   -  person Jeff    schedule 28.01.2018


Ответы (1)


Ваша функция не возвращает никакого значения, которое приводит к отправке пустого сообщения на server.sendmail.

Попробуйте это вместо этого:

def query_named_params(corpus, min_word_count):

    (...)

    query_params = [
        bigquery.ScalarQueryParameter('corpus', 'STRING', corpus),
        bigquery.ScalarQueryParameter(
            'min_word_count', 'INT64', min_word_count)
    ]

    (...)
    s = ""
    for row in resulters:
        s+= "{} : {} views\n".format(row.word, row.word_count))
    return s

(...)
server.sendmail(login_email, recipients, query_named_params('sonnets', 10))

Это, вероятно, не будет отправлять очень читаемое сообщение. В зависимости от сложности результатов из вашей таблицы BQ я бы рекомендовал использовать Jinja2 для создания HTML-шаблон, а затем рендеринг его для отправки в качестве тела письма.

person Willian Fuks    schedule 29.01.2018
comment
Это помогает совмещать многие вещи. Он отлично печатается на терминале, но по-прежнему не отображается в электронной почте. Это означает, что я могу выполнить print(query_named_params('corpus', 'min_word_count') и распечатать строки. Но они не возвращаются при отправке электронного письма в теле. - person Jeff; 29.01.2018
comment
вы должны указать corpus значение, иначе оно не определено для интерпретатора, что-то вроде: print(query_named_params('sonnets', 10)) - person Willian Fuks; 29.01.2018
comment
Если я сделаю это здесь, server.sendmail(login_email, получатели, query_named_params('sonnets', '10')) он все равно ничего не вернет в теле письма. Также я пытаюсь использовать параметры запроса в поиске. Это часть Шекспира является примером, в конечном итоге я хочу иметь возможность передавать строку даты в запрос и другие переменные. Затем верните результаты этого на электронную почту. Кажется, что эта часть спотыкается. - person Jeff; 29.01.2018
comment
каков результат print(query_named_params('sonnets', 10))? - person Willian Fuks; 29.01.2018
comment
Он возвращает все результаты. Похоже, что когда функция вызывается в server.sendmail(), либо вывод данных, либо тип данных, либо полученный результат каким-то образом несовместимы. Например: 363 просмотра: 351 просмотр I: 342 просмотра my: 335 просмотров to: 335 просмотров in: 287 просмотров и: 247 просмотров And: 242 просмотра thy: 240 просмотров - person Jeff; 29.01.2018
comment
и каков результат print(query_named_params('sonnets', '10')) (последние 10 - это str) - person Willian Fuks; 29.01.2018
comment
Я получаю тот же вывод, что и строка - person Jeff; 29.01.2018
comment
хм странно. Как и в предыдущем вопросе, я полностью протестировал ваш код, и он у меня работает; где-то в вашем коде есть ошибка. Убедитесь, что вы вызываете метод как server.sendmail(login_email, recipients, query_named_params('sonnets', 10)), кроме этого вам нужно будет найти, где ошибка. - person Willian Fuks; 29.01.2018
comment
Я ценю всю помощь! Я буду продолжать подключаться и посмотреть, смогу ли я понять это. - person Jeff; 29.01.2018
comment
Давайте продолжим обсуждение в чате. - person Jeff; 30.01.2018