您的位置:首页 > 编程语言 > Python开发

【详解】Python每小时脚本中---<取数据库函数>和<发邮件问题>

2016-01-07 18:14 471 查看
本例我们的需求是,写一个脚本,每个小时跑一次,并把生成的txt文件发送邮件。

是很简单的需求。有三个问题需要简单阐述一下:

【问题一:写txt文件】

本例由于比较急,所以数据取出来写到了txt文件中。

其实,Python写文件,写txt文件本来就是最快也最省事儿的。

许久不写,忘了是什么代码了。这里当做复习。

方法如下:

不需要引入任何的包,直接就可以写。

def writeTxt():
'''写数据'''
f=open(orifileName, 'a')
f.write('充值:'+str(genChargeHistoryData())+'\n')
f.write('银行汇款:'+str(genRemittanceHistory())+'\n')
f.close()

即,写txt文件的步骤就是:

open---write---close

甚至不需要担心中文乱码的问题,很方便!

【txt文件的a模式与w模式】

其中的'a'

表示追加模式,不会覆盖文件原有的内容。

换为'w'模式后,

表示覆盖模式,再写,就会覆盖文件原有的内容

其中的文件名:

orifileName = fileDir+'per_hour_data_'+dateStr+'.txt'


【Linux环境下的换行符】

其中的换行符

'\n'

要记得加上。只是关于换行符要注意一点。

我们在本地测试的时候,生成的文件用记事本打开,数据是一行一行的,换行是成功的。

但是放到线上运行生成的文件,用记事本打开,数据是连在一起的,换行符没起作用。

这是为什么呢?

首先,两种情况下,用EditPlus或者其他文本编辑工具打开文件,即使是线上发送过来的文件,打开也是有换行的。

是因为,文本编辑工具可以检测到换行符。

而记事本是不具备这样的功能的。

其次,为什么单单线上的文件会出现这样的情况呢?

因为脚本在线上运行,即,在服务器上运行的时候,运行环境由windows换成了Linux。

问题就出在这里。因为,Linux对换行符

'\n'

的支持不好。不同于windows环境,所以,才会出现这样的问题。

解决方法?\n改为\r\n。也许可以吧。。。

【问题二:取数据库数据的函数的理解】

如下,使我们最终版的代码。

def genChargeHistoryData():
'''充值'''
sql = '''
SELECT SUM(AMOUNT_ACT)
FROM netgame_trade.CHARGE_HISTORY
WHERE CHARGE_DATE >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 HOUR), '%Y-%m-%d %H')
AND CHARGE_DATE < DATE_FORMAT(NOW(), '%Y-%m-%d %H')
AND STATUS = 1
AND AMOUNT > 0
AND CHARGE_STATUS = 1;
'''
rs = ngTradeDBUtil.queryCount(sql)
if not rs: return 0
return rs

注意这一句:

rs = ngTradeDBUtil.queryCount(sql)


原先这个函数是这样的。

def genChargeHistoryData():
'''充值'''
sql = '''
SELECT SUM(AMOUNT_ACT)
FROM netgame_trade.CHARGE_HISTORY
WHERE CHARGE_DATE >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 HOUR), '%%Y-%%m-%%d %%H')
AND CHARGE_DATE < DATE_FORMAT(NOW(), '%%Y-%%m-%%d %%H')
AND STATUS = 1
AND AMOUNT > 0
AND CHARGE_STATUS = 1;
'''
rs = ngTradeDBUtil.queryCount(sql,())
if not rs: return 0
return rs


为什么是两个百分号,我们之前没有去深究过。

为什么要在

rs = ngTradeDBUtil.queryCount(sql,())

这个的参数中加一个空的括号,也不知道。

本例我们了解了。如上的空括号,表示参数,因为我们有时候会有这种取数据库数据的方法。

def gen5pointsNumber():
'''5积分人数'''
sql = '''
SELECT COUNT(DISTINCT MEMBER_ID)
FROM moyoyo_point.MEMBER_POINT_HISTORY
WHERE CREATED_DATE >= '%s'
AND CREATED_DATE < '%s'
AND POINT = 5
AND TYPE = 1005;
''' %(handleStr, todayStr)
rs = pointDBUtil.queryCount(sql, ())
if not rs: return 0
return rs


SQL的参数是用%挂在外面的。

这种情况下,才需要这样的语句

rs = pointDBUtil.queryCount(sql, ())

如果没有外挂参数,就不需要了
rs = ngTradeDBUtil.queryCount(sql)


【问题三:线上发邮件的方式】

发邮件我们做了很多次了。还是没有覆盖全。

先回顾一下以前的,有这么几种情况:

1. 完全由我们自己写。生成文件到发送邮件成功,整个过程脚本可以单独完成。

2. 我们完全不用写,只需要生成文件,在脚本后台配置生成的文件名,配置邮件接收人,就可以了。

    这种情况,我们不需要写发送邮件的函数。只需要在脚本中声明,拿到配置文件名即可。

   beforeFilePath = fileDir + execute.getReportFileName(beforeDate)


这行代码是记录微信签到结果的脚本中的getFileName代码。为什么是beforeDate呢?

不知道。。。需要思考一下。。

这里我们遇到的是第三种情况。

3.我们需要在脚本中声明,拿到邮件接收人。

   我们需要在脚本中定义生成文件的名称。

   我们需要写发送邮件的方法。

   即,只有邮件接收人不是我们负责!其它的都是我们自己做。

   就是方便了设置邮件接收人而已。

mailToUsers = execute.getReceiverEmailAddressList()

strTo = mailToUsers
msg['to'] = ','.join(strTo)


第三种情况最关键的代码就是以上三行。记住即可。

其实就是一个get邮件接收人的函数而已。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: