ETL应用:一种一次获取一个平台接口文件的方法

ETL应用场景中,若对端接口文件未能提供,任务会处于循环等待,直到对端提供为止,该方法极大的消耗了系统资源。为此想到了一种方法,一次获取一个平台的文件,实现思路如下:

1、第一次获取对端平台提供目录下给定日期的所有接口文件,并保存文件列表;

2、后续每隔n分钟重启获取任务,每次先获取文件列表,和上次列表进行对比,当发生如下情况时,会重新获取:

A、有新文件产生;

B、有文件大小变化

实现方法如下:

[ftp.properties]

ipaddress = 10.25.xxx.xxx
username = xxxxx
password = xxxxx

#\u5F53 encryption \u6709\u503C\u65F6\uFF0C\u5C06\u8FDB\u884C\u5BC6\u7801\u89E3\u6790
encryption = 

#\u5F53resolve \u4E3A False\u65F6\uFF0C\u9700\u8981\u66FF\u6362\u8FDC\u7A0B\u76EE\u5F55\u548C\u5F53\u524D\u76EE\u5F55\u7684\u53C2\u6570
resolve = 1
remoteDir = /bosscdr/tobak/jf_bass
localDir = /interface/cyg/[SDT_YYYYMMDD]

#\u4E0A\u6B21\u4FDD\u5B58\u7684\u6587\u4EF6\u83B7\u53D6\u5217\u8868
lastFileList = /interface/cyg/lastfilelist.txt
# -*-  coding:utf-8 -*-
‘‘‘
函数说明 :获取远程文件
编写时间: 2015-5-5
编 写 人 : chenyangang
----------------------------------------
实现方法:
   1、获取配置文件中制定的ftp服务器信息,用户名采用加密方式
   2、获取远程目录下的文件列表,若存在保存的文件列表,进行比对,提取差异文件
   3、根据差异文件进行文件获取
‘‘‘
import datetime
import ConfigParser
import os
import ftplib
import cPickle

class GetDataBaseDiff(object):

    def __init__(self, config, interfaceID = None, interfaceDate = None, delay = 0):
        self.config = config
        self.interfaceID = interfaceID

        #默认为当天日期
        if interfaceDate == None:
            self.interfaceDate = datetime.date.strftime(datetime.date.today() -                                  datetime.timedelta(delay),"%Y%m%d")

    def getConfig(self, interfaceDate):

        readConfig = ConfigParser.ConfigParser()
        with open(self.config,‘r‘) as configFile:

            readConfig.readfp(configFile)
            hostaddr = readConfig.get(‘ftp.properties‘,‘ipaddress‘)
            username = readConfig.get(‘ftp.properties‘,‘username‘)          

            #是否解析参数和加密
            resolve = readConfig.get(‘ftp.properties‘,‘resolve‘)
            encryption = readConfig.get(‘ftp.properties‘,‘encryption‘)

            #目录信息
            remoteDir = readConfig.get(‘ftp.properties‘,‘remoteDir‘)
            localDir = readConfig.get(‘ftp.properties‘,‘localDir‘) 

            #存储上次获取文件列表
            lastFileList = readConfig.get(‘ftp.properties‘,‘lastFileList‘) 

            if encryption == ‘‘ :
                password = readConfig.get(‘ftp.properties‘,‘password‘)
            else:
                command = encryption + ‘ ‘ + readConfig.get(‘ftp.properties‘,‘password‘)
                password = os.popen(command)

            if resolve == ‘1‘ :
                month = interfaceDate[0:6]
                remoteDir = remoteDir.replace(r"[SDT_YYYYMMDD]", interfaceDate)
                remoteDir = remoteDir.replace(r"[SDT_YYYYMM]",month)

                localDir = localDir.replace(r"[SDT_YYYYMMDD]", interfaceDate)
                localDir = localDir.replace(r"[SDT_YYYYMM]",month)

        return hostaddr, username, password, remoteDir, localDir, lastFileList

    def connect(self, hostaddr, username, password):

        try:
            connftp = ftplib.FTP(hostaddr)
        except ftplib.error_perm:
            print "The ipaddress (ipaddress) refused!" %{‘ipaddress‘:hostaddr}

        try:
            connftp.login(username, password)
        except ftplib.error_perm:
            print "This username (username) refuse connect, please check your                         username or password!" %{‘username‘:username}

        return connftp

    def getFileList(self, connftp, remoteDir):

        #获取文件详细信息,包括权限、文件大小、属主等信息,其中第5项为文件大小
        connftp.cwd(remoteDir)
        filesDetail = connftp.nlst(‘-l‘)

        #保存文件名称和大小
        fileList = {}

        for fileDetail in filesDetail:
            filelistFromDetail = fileDetail.strip().split()
            fileList[filelistFromDetail[-1]] = filelistFromDetail[4]

        return fileList

    def comparisonFileList(self, lastFileList, newFileList):

        #装载上一次文件获取信息

        if len(open(lastFileList, "rb").readlines()) > 0 :
            with open(lastFileList, "rb") as fp:
                try:
                    lastfileList = cPickle.load(fp)
                except EOFError:
                    print "Load (filename) was failed"%{‘filename‘:lastFileList}
        else:
            lastfileList={}

        lastfileset = set(lastfileList.keys())
        newfileSet = set(newFileList.keys())

        #提取新增文件列表
        diffFileList = list(newfileSet - lastfileset)
        sameFileName = list(newfileSet & lastfileset)

        #提取前后文件大小不一致的文件列表
        for samefilename in sameFileName:
            if newFileList[samefilename] != lastfileList[samefilename]:
                diffFileList.append(samefilename)

        del lastfileList
        #保存最新文件获取列表
        fp = open(lastFileList, "wb")

        lastfileList = cPickle.dump(newFileList, fp)
        fp.close()

        return diffFileList

    def machedFileList(self, diffFileList, interfaceID, interfaceDate):
        return [flist for flist in diffFileList if interfaceID in flist                                               and interfaceDate in flist] 

    def download(self, connftp, localDir, getFileList):

        #进入本地目录
        if not os.path.isdir(localDir) :
            os.makedirs(localDir)

        try:
            os.chdir(localDir)
        except :
            print ‘Dose\‘t enter the directory , mybe you have not authority!‘

        #获取最新文件
        for remotefile in getFileList:
            try:
                connftp.retrbinary("RETR %s"%remotefile, open(remotefile,"wb").write)
            except ftplib.error_perm:
                print ‘ERROR: cannot read file "%s"‘ % remotefile

        connftp.quit()

if __name__ == ‘__main__‘ :
    interfaceDate = ‘20150520‘
    interfaceID = None
    getDataBaseDiff = GetDataBaseDiff(‘./config.properties‘, interfaceDate, 0)
    hostaddr, username, password, remoteDir, localDir, lastFileList = getDataBaseDiff.getConfig(interfaceDate)

    connectionFtp = getDataBaseDiff.connect(hostaddr, username, password)

    fileList = getDataBaseDiff.getFileList(connectionFtp, remoteDir)
    diffFileList = getDataBaseDiff.comparisonFileList(lastFileList, fileList)

    if interfaceID is not None and len(diffFileList) >0:
        getFileList = getDataBaseDiff.machedFileList(diffFileList, interfaceID, interfaceDate)
        getDataBaseDiff.download(connectionFtp, localDir, getFileList)
    else:
        getDataBaseDiff.download(connectionFtp, localDir, diffFileList)

如上,是学习python后,尝试编写的代码。可修改为配置文件中配置多个平台,获取多平台接口数据。

时间: 2024-10-25 23:58:22

ETL应用:一种一次获取一个平台接口文件的方法的相关文章

FileTest 删除一个目录或文件的方法

/** * 删除一个目录或文件的方法 * */ public class FileTest { public static void main(String[] args) { File dir = new File("a"); //删除a目录 delete(dir); System.out.println("删除完毕!"); } public static void delete(File file) { //1.判断file是文件还是目录? if(file.is

JS中对获取一个标签的class的方法封一个库

在JS中我们经常会会用到,获取一个标签的id var aId=document.getElementById("id") 现在虽然有getElementsByClassName这个方法,但是这个方法再ie6下兼容性存在问题,所以保险起见还是封一个获取class的库 首先先看库 /** * Created by asus on 2016/12/4 By dirk_jian. */ function getByclass(oParent,sClass){ var aEle=oParent.

一种基于二维码的半自动文件拷贝方法

在一种受限的环境中,要把文件拷贝出去显然是不可能的.因为既不能进行直接的文本拷贝(Ctrl+C, Ctrl+V),又不能使用scp(因为网络隔离).那么,真的一点办法都木有了吗?答案是否定的,因为毛主席说过,"卑贱者最聪明,高贵者最愚蠢".作为一个好琢磨的程序员,因为好奇("与天斗,其乐无穷:与地斗,其乐无穷:与人斗,其乐无穷."),所以很快想出了一个解决的办法,那就是利用非常盛行的二维码技术.虽然全自动拷贝不好实现,但半自动拷贝还是非常容易做到的.于是,本文尝试利

使用fuser命令kill一个终端(特殊文件)的方法

/*********************************************************************  * Author  : Samson  * Date    : 11/04/2014  * Test platform:  *              3.13.0-24-generic  *              GNU bash, 4.3.11(1)-release  * ************************************

使用五种以上方式获取一个文件的扩展名

要求:dir/upload.image.jpg,找出 .jpg 或者 jpg ,必须使用PHP自带的处理函数进行处理,方法不能明显重复,可以封装成函数,比如 get_ext1($file_name), get_ext2($file_name) 第一种: <?php $string= 'dir/upload.image.jpg'; $tok = strtok($string, '.'); //使用strtok将字符串分割成一个个令牌 while ($tok) { $arr[]= $tok; $to

用js如何获取一个上传文件的扩展名

function suffix(file_name){     var result =/\.[^\.]+/.exec(file_name);     return result; }

ASP.NET之MVC 微信公众号授权给第三方平台的技术实现流程一(获取第三方平台access_token)

“出于安全考虑,在第三方平台创建审核通过后,微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据”.这是文档中的原话,也就是说我们在获取access_token的时候是要先得到component_verify_ticket的,而component_verify_ticket是每10分钟向我们的接收地址推送一次. 而域名地址是由我们自己去服务器上去部署,如下图: /// <summary> /// 一.推送compo

java进阶之反射:反射基础之如何获取一个类以及如何获取这个类的所有属性和方法(1)

java学习一段时间之后,大家可能经常会听到反射这个词,那么说明java已经学习到一个高一点的层次了.接下来我会一步步和大家一起揭开java高级特性反射的神秘面纱. 首先介绍下类对象这个概念,可能会经常用到这个概念: 类对象:java中有句很经典的话"万事万物皆对象",相信大家都不陌生,这句话告诉了我们java的特征之一,那就是面向对象.java中类的概念我们都很熟悉,既然万事万物皆是对象,那么类是谁的对象呢?<对象的概念:一个类的实例>换句话说,类是谁的实例.如此就有了类

Entity Framework 6 Recipes 2nd Edition(13-2)译 -&gt; 用实体键获取一个单独的实体

问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Painting(绘画)类型的实体,如Figure 13-2所示: Figure 13-2. The Painting entity type in our model 在代码In Listing 13-2,我们创建实体类Painting. public class Painting { public str