# -*- coding:utf8 -*- ''' Created on 2016年11月29日 @author: qiancheng ''' import MySQLdb from email.mime.text import MIMEText from email.header import Header import smtplib import redis import datetime from decimal import Decimal class do_redis(): def __init__(self,_redishost,_redisport,_redispasswd,_db): do_redis=redis.ConnectionPool(host=_redishost,port=_redisport,password=_redispasswd,db=_db) self.redis_cli=redis.Redis(connection_pool=do_redis) def set_redis(self,_hash_name,_hash_keys): self.redis_cli.hmset(_hash_name, _hash_keys) def get_redis(self,_hash_name): print self.redis_cli.hgetall(_hash_name) class mail_to: def __init__(self,_message): self.message=_message mail_host="115.231.109.86" #smtp-server mail_user="qiancheng" #username mail_pass="xxxx" #password sender = 'qiancheng@showjoy.com' receivers = ['xxxx@showjoy.com'] message = MIMEText(self.message,'plain','utf-8') message['From'] = Header("qiancheng@showjoy.com<qiancheng@showjoy.com>") message['To'] = Header("xxxx@showjoy.com<xxxx@showjoy.com>") subject = '达人店交易信息统计' message['Subject'] = Header(subject,'utf-8') try: smtpObj=smtplib.SMTP() smtpObj.connect(mail_host) smtpObj.login(mail_user,mail_pass) smtpObj.sendmail(sender, receivers, message.as_string()) smtpObj.close() except smtplib.SMTPException: print("Error: 无法发送邮件") shopdbinfo={'host':'xxxxx','user':'root','port':22306,'passwd':'xxxx','db':'shop'} tradedbinfo={'host':'xxxxx','user':'root','port':10306,'passwd':'xxxx','db':'trade'} class do_db(object): def __init__(self,_host,_port,_user,_passwd,_db): self.host=_host self.port=_port self.passwd=_passwd self.dbf=_db self.user=_user self.db=MySQLdb.connect(host=self.host,user=self.user,passwd=self.passwd,port=self.port,db=self.dbf) self.cursor=self.db.cursor(MySQLdb.cursors.DictCursor) def execsql(self,_sql): self.sql=_sql self.cursor.execute(self.sql) return self.cursor.fetchoneDict() def closedb(self): self.cursor.close() self.db.close() def get_order_monitor(): now=datetimes day=str(now.strftime('%Y-%m-%d'))+'%' _times=day #计算前一日的统计信息sql语句 '''sql_recommission='SELECT shop_commission_order_r.ORDER_NUMBER recommission_resql from shop.shop_commission_order_r,shop.shop_commission \ where SHOP_COMMISSION_ID = ID and shop_commission.IS_DELETE = 0 and \ shop_commission_order_r.gmt_modified BETWEEN DATE_SUB(NOW(),INTERVAL 1 day) and NOW() \ group by SHOP_ID,COMMISSION,COMMISSION_TYPE,shop_commission_order_r.GMT_CREATE,ORDER_NUMBER,SKU_ID \ having count(*)>1' ''' sql_oneday_recruit='select count(DISTINCT sr.recruit_shop_id)*360 one_day_startshop \ from shop.shop_commission_recruit_r as sr \ where sr.gmt_modified like \''+_times+'\' and sr.is_delete = 0' sql_oneday_recruit_comm='select sum(sc.COMMISSION) one_day_startshop_commisson \ from shop.shop_commission as sc \ where (sc.COMMISSION_TYPE = 201 or sc.COMMISSION_TYPE = 301) \ and sc.gmt_modified like \''+_times+'\' and sc.is_delete = 0' sql_oneday_order='SELECT SUM(tpr.actual_price) one_day_order FROM trade.trade_pay_record tpr \ LEFT JOIN trade.trade_order_pay_record_r topr ON tpr.id = topr.pay_record_id \ LEFT JOIN trade.trade_order tr ON topr.order_number = tr.order_number \ WHERE tpr.paid_time like \''+_times+'\' AND tr.source_type = 1 and tr.IS_CANCEL = 0' sql_oneday_order_comm='select sum(sc.COMMISSION) one_day_order_commission from shop.shop_commission as sc \ where (sc.COMMISSION_TYPE = 200 or sc.COMMISSION_TYPE = 300 and sc.is_delete = 0) \ and sc.gmt_modified like \''+_times+'\'' '''计算一天开店收入''' todo=do_db(shopdbinfo['host'],shopdbinfo['port'],shopdbinfo['user'],shopdbinfo['passwd'],shopdbinfo['db']) one_day_startshop = todo.execsql(sql_oneday_recruit)['one_day_startshop'] todo.closedb() if one_day_startshop is None: one_day_startshop = 0 '''计算一天开店发放的收益''' todo=do_db(shopdbinfo['host'],shopdbinfo['port'],shopdbinfo['user'],shopdbinfo['passwd'],shopdbinfo['db']) one_day_startshop_commisson = todo.execsql(sql_oneday_recruit_comm)['one_day_startshop_commisson'] todo.closedb() if one_day_startshop_commisson is None: one_day_startshop_commisson = 0 '''查询重复发放收益''' '''todo=do_db(shopdbinfo['host'],shopdbinfo['port'],shopdbinfo['user'],shopdbinfo['passwd'],shopdbinfo['db']) recommission_resql = todo.execsql(sql_recommission) todo.closedb() if recommission_resql is None: recommission_resql = 0 ''' '''计算一天订单总额''' todo=do_db(tradedbinfo['host'],tradedbinfo['port'],tradedbinfo['user'],tradedbinfo['passwd'],tradedbinfo['db']) one_day_order = todo.execsql(sql_oneday_order)['one_day_order'] todo.closedb() if one_day_order is None: one_day_order = 0 '''计算一天订单收益总额''' todo=do_db(shopdbinfo['host'],shopdbinfo['port'],shopdbinfo['user'],shopdbinfo['passwd'],shopdbinfo['db']) one_day_order_commission = todo.execsql(sql_oneday_order_comm)['one_day_order_commission'] todo.closedb() if one_day_order_commission is None: one_day_order_commission = 0 if one_day_startshop != 0: recruitpercent=one_day_startshop_commisson/one_day_startshop*100 else: recruitpercent=0 if one_day_order != 0: orderpercent=one_day_order_commission/one_day_order*100 else: orderpercent=0 '''if recommission_resql != 0: recommission_message='一天内有重复发放收益的订单存在,请查询数据库确认!' else: recommission_message='一天内没有重复发放收益。' ''' '''final_result='%s \n一天开店总金额:%d,一天开店发放收益:%d,收益发放比例:%.2f \n一天达人店订单总额:%d,一天达人店订单发放收益:%d。收益发放比例:%.2f' \ %(recommission_message,one_day_startshop,one_day_startshop_commisson,recruitpercent,one_day_order,one_day_order_commission,orderpercent) #print (str(final_result))''' order_monitor_info={'startshop':float(Decimal(str(one_day_startshop)).quantize(Decimal('0.00'))), 'startshop_commisson':float(Decimal(str(one_day_startshop_commisson)).quantize(Decimal('0.00'))), 'recruitpercent':float(Decimal(str(recruitpercent)).quantize(Decimal('0.00'))), 'order':float(Decimal(str(one_day_order)).quantize(Decimal('0.00'))), 'order_commission':float(Decimal(str(one_day_order_commission)).quantize(Decimal('0.00'))), 'orderpercent':float(Decimal(str(orderpercent)).quantize(Decimal('0.00'))) }#算出订单统计的结果并且保留2位小数 return order_monitor_info #mail_to(str(final_result)) def set_order_monitor(_order_monitor_info): now=datetimes key_name=str(now.strftime('%Y-%m-%d')) hash_name='order_monitor'#hash的名字 test_redis_info={'redishost':'192.168.0.223','redisport':'6380','password':'xxxxx','db':10}#线下的redis信息 increment_redis_info={'redishost':'xxxx','redisport':'6379','password':'xxxxxx','db':8}#线上的redis信息 hash_keys={key_name:str(_order_monitor_info)}#key_name就是日期,value就是string化的统计的订单结果 if env=='test': r=do_redis(test_redis_info['redishost'],test_redis_info['redisport'],test_redis_info['password'],test_redis_info['db']) elif env=='increment': r=do_redis(increment_redis_info['redishost'],increment_redis_info['redisport'],increment_redis_info['password'],increment_redis_info['db']) else: print '请选择正确的环境参数' exit() r.set_redis(hash_name,hash_keys) r.get_redis(hash_name) if __name__ == '__main__': global datas global year global month global day global datetimes global env env='increment' datas='all' year=int(datetime.datetime.now().strftime('%Y')) month=int(datetime.datetime.now().strftime('%m')) day=int(datetime.datetime.now().strftime('%d')) d1=datetime.datetime(2016,07,01) d2=datetime.datetime(year,month,day) if datas=='all': day_values=int((d2-d1).days) elif datas=='one': day_values=0 else: print '请选择正确的数据量参数' exit() for i in range(0,day_values+1): datetimes=datetime.date(datetime.date.today().year,datetime.date.today().month,datetime.date.today().day)-datetime.timedelta(i) order_monitor_result=get_order_monitor() set_order_monitor(order_monitor_result)
把按天计算的数据存放到redis中,避免每次读取都要使用mysql的查询很慢,redis使用hash模式,key值定义好后,value就是{日期:json}这样的格式。读取出来的时候再进行json序列化就可以了。小数位的保留使用了Decimal,其实用round更简单一些,但是做这个事情的时候发现了个bug,python2.6使用round和Decimal都会出现四舍五入不精确导致float过长的问题,升级成2.7就好了。这个脚本可以做成参数启动的,觉得麻烦没写。就直接改global 参数了。
PS:邮件class没有使用,redis的数据结构是这样的:
'2016-12-02': "{'order_commission': 8521.8, 'recruitpercent': 70.61, 'orderpercent': 15.35, 'startshop_commisson': 20336.0, 'startshop': 28800.0, 'order': 55501.86}"