获取远程文本文件,处理并更新数据库 - 采用何种方法和脚本语言?
我最近在处理一些基本的数据提取工作。具体来说,就是通过ftp获取一个文件,处理它(也就是提取我关心的字段),然后更新本地数据库。同样的,反方向也是:从数据库获取数据,生成文件,然后通过ftp上传。这些脚本会被定时任务(cron)调用。
我想每种数据提取类型都应该定义ftp连接和文件信息。然后需要有一种方式来翻译文件中的数据字段与应用程序可以使用的数据字段之间的关系(当然还要处理这个翻译)。另外,还要编写单独的脚本,处理不同对象的常见插入功能,这些对象可能在不同的数据提取中使用。
举个电商的例子,假设我和不同的供应商合作,他们给我提供数据提取。数据提取的类型可能不同(对象类型):产品、类别或订单信息。对于每种类型的数据提取,我显然会处理不同的字段,并调用不同的更新或插入脚本。
那么,最适合用什么语言来实现这个呢?我会使用PHP,但也想找一个项目来学习Perl或Python,所以这个项目对我来说也不错。
如果用Perl或Python,能简单说一下高层次的实现吗?比如如何分离不同的脚本,面向对象的方法?如何方便将来添加新的数据提取或处理功能等等。
[说明一下:之前已经用PHP写了一些类,我最近用它们创建了一个新的数据提取。我已经完成了工作,但过程非常混乱且困难。所以这个问题并不是“请帮我完成工作”,而是我自己发展时的“最佳方法”类型的问题。]
谢谢!
4 个回答
Python.
第一,问一下,这些通过FTP传输的文件是什么格式?我假设它们是CSV格式的。
第二,你是怎么知道什么时候运行FTP获取的?是固定的时间表吗?还是某个事件触发?我假设是固定的时间表。你可以用cron来控制这个。
你有三个问题需要解决:FTP获取、数据提取和数据库加载。
ftp_get_load.py
import ftplib
import csv
import someDatabaseAPI as sql
class GetFile( object ):
... general case solution using ftplib ...
class ExtractData( object ):
... general case solution using csv ...
class LoadDB( object ):
... general case solution using sql ...
some_load.py
import ftp_get_load
class UniqueExtractor( ftp_get_load.ExtractData ):
... overrides ...
get = GetFile( url, filename, etc. )
extract = UniqueExtractor( filenamein, filenameout, etc. )
load = LoadDB( filename, etc. )
if __name__ == "__main__":
get.execute()
extract.execute()
load.execute()
这主要取决于你要传输的文件格式。如果文件格式很复杂,是某种专有格式,你可能只能用已经有相关库的编程语言来处理。如果是CSV或XML格式,那几乎任何编程语言都可以用。
- FTP:可以用Net::FTP这个库。
- 解析:如果是CSV或用制表符分隔的文件,可以用Text::CSV_XS;如果是XML文件,可以用XML::Twig。
- 插入数据:可以用DBI配合你合适的数据库驱动,不过也有更高级的封装,比如DBIx::Class。
这些只是举个例子。看起来挺简单的,但我几乎每天都在用Perl ;-)
说哪个编程语言是“最好”的,其实是个见仁见智的问题。一般来说,Python被认为比较容易学,也容易读懂,而Perl常常被开玩笑称为“只写不读”的语言。不过,Perl在网络管理方面用得很广泛。相对来说,Python更多用于系统管理或者大型编程。两者各有擅长的地方,也有不太适合的地方。
无论用哪种语言,你都能比较轻松地解决问题。它们都有必要的模块,要么是打包好的库,要么是很容易找到的。
如果我用Python的话,我会使用ConfigParser
http://docs.python.org/library/configparser.html#module-ConfigParser
来存储每个项目的设置,使用ftplib:
http://docs.python.org/library/ftplib.html
来和ftp服务器进行交流,还会用到很多数据库库。例如,如果你用的是Postgres:
最后,对于命令行选项,我会使用Python自带的优秀选项解析模块:
http://docs.python.org/library/optparse.html#module-optparse
从代码的角度来看,我会有以下这些对象:
# Reads in a config file, decides which feed to use, and passes
# the commands in to one of the classes below for import and export
class FeedManager
# Get data from db into a canonical format
class DbImport
# Put data into db from a canonical format
class DbExport
# Get data from ftp into a canonical format
class FtpImport
# Put data into ftp from canonical format
class FtpExport
每个类都能转换成一种标准格式,这种格式可以交给其他互补的类使用。
配置文件可能长这样:
[GetVitalStats]
SourceUrl=ftp.myhost.com
SourceType=FTP
Destination=Host=mydbserver; Database=somedb
SourceType=Postgres
最后,你可以这样调用它:
process_feed.py --feed=GetVitalStats