Singer 修改tap-s3-csv 支持minio 连接
singer 团队官方处了一个tap-s3-csv 的tap,对于没有使用aws 的人来说并不是很方便了,所以简单修改了
下源码,可以支持通用的s3 csv 文件的处理,同时发布到了官方pip 仓库中,方便大家使用。
以下是简单代码修改部分的说明,以及如何发布pip包
修改说明
主要是关于连接s3 的部分,因为tap-s3-csv 使用的是boto3 我们需要修改的就是关于boto3 连接s3 的部署
添加上aws_access_key_id,aws_secret_access_key,endpoint_url
关于s3 自定义连接的说明,格式如下:
s3_client = boto3.session.Session().client(
service_name='s3',
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
endpoint_url=endpoint_url,
)
几个需要修改的部分
- s3.py
get_input_files_for_table 部分,主要是传递参数的
修改如下:
def get_input_files_for_table(config, table_spec, modified_since=None):
bucket = config['bucket']
aws_access_key_id = config['aws_access_key_id']
aws_secret_access_key =config['aws_secret_access_key']
endpoint_url =config['endpoint_url']
to_return = []
pattern = table_spec['search_pattern']
try:
matcher = re.compile(pattern)
except re.error as e:
raise ValueError(
("search_pattern for table `{}` is not a valid regular "
"expression. See "
"https://docs.python.org/3.5/library/re.html#regular-expression-syntax").format(table_spec['table_name']),
pattern) from e
LOGGER.info(
'Checking bucket "%s" for keys matching "%s"', bucket, pattern)
matched_files_count = 0
unmatched_files_count = 0
max_files_before_log = 30000
for s3_object in list_files_in_bucket(bucket,aws_access_key_id,aws_secret_access_key,endpoint_url, table_spec.get('search_prefix')):
key = s3_object['Key']
last_modified = s3_object['LastModified']
LOGGER.info(key)
LOGGER.info(last_modified)
if s3_object['Size'] == 0:
LOGGER.info('Skipping matched file "%s" as it is empty', key)
unmatched_files_count += 1
continue
if matcher.search(key):
matched_files_count += 1
if modified_since is None or modified_since < last_modified:
LOGGER.info('Will download key "%s" as it was last modified %s',
key,
last_modified)
yield {'key': key, 'last_modified': last_modified}
else:
unmatched_files_count += 1
if (unmatched_files_count + matched_files_count) % max_files_before_log == 0:
# Are we skipping greater than 50% of the files?
if 0.5 < (unmatched_files_count / (matched_files_count + unmatched_files_count)):
LOGGER.warn(("Found %s matching files and %s non-matching files. "
"You should consider adding a `search_prefix` to the config "
"or removing non-matching files from the bucket."),
matched_files_count, unmatched_files_count)
else:
LOGGER.info("Found %s matching files and %s non-matching files",
matched_files_count, unmatched_files_count)
if 0 == matched_files_count:
raise Exception("No files found matching pattern {}".format(pattern))
list_files_in_bucket 修改核心部分,关于连接s3 的
修改如下:
@retry_pattern()
def list_files_in_bucket(bucket,aws_access_key_id,aws_secret_access_key,endpoint_url, search_prefix=None):
s3_client = boto3.session.Session().client(
service_name='s3',
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
endpoint_url=endpoint_url,
)
s3_object_count = 0
max_results = 1000
args = {
'Bucket': bucket,
'MaxKeys': max_results,
}
if search_prefix is not None:
args['Prefix'] = search_prefix
paginator = s3_client.get_paginator('list_objects_v2')
pages = 0
for page in paginator.paginate(**args):
pages += 1
LOGGER.debug("On page %s", pages)
s3_object_count += len(page['Contents'])
yield from page['Contents']
if 0 < s3_object_count:
LOGGER.info("Found %s files.", s3_object_count)
else:
LOGGER.warning('Found no files for bucket "%s" that match prefix "%s"', bucket, search_prefix)
get_file_handle 部分,主要是关于获取s3 对象内容的
@retry_pattern()
def get_file_handle(config, s3_path):
bucket = config['bucket']
aws_access_key_id = config['aws_access_key_id']
aws_secret_access_key =config['aws_secret_access_key']
endpoint_url =config['endpoint_url']
s3_client = boto3.resource(
service_name="s3",
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
endpoint_url=endpoint_url)
s3_bucket = s3_client.Bucket(bucket)
s3_object = s3_bucket.Object(s3_path)
return s3_object.get()['Body']
- init.py
关于tap 命令处理的部分,比如模式发现,执行同步,以及参数检验的
参数校验修改,修改为我们配置参数需要的
REQUIRED_CONFIG_KEYS = ["start_date", "bucket", "aws_access_key_id", "aws_secret_access_key", "endpoint_url"]
main 函数:
@singer.utils.handle_top_exception(LOGGER)
def main():
args = singer.utils.parse_args(REQUIRED_CONFIG_KEYS)
config = args.config
bucket = config['bucket']
aws_access_key_id = config['aws_access_key_id']
aws_secret_access_key =config['aws_secret_access_key']
endpoint_url =config['endpoint_url']
config['tables'] = validate_table_config(config)
try:
for page in s3.list_files_in_bucket(bucket,aws_access_key_id,aws_secret_access_key,endpoint_url):
break
LOGGER.warning("I have direct access to the bucket without assuming the configured role.")
except:
LOGGER.error("can't connect to s3 storage")
if args.discover:
do_discover(args.config)
elif args.properties:
do_sync(config, args.properties, args.state)
- pip 包约定处理
为了不和官方冲突,重新别名
setup.py:
#!/usr/bin/env python
from setuptools import setup
setup(name='tap-minio-csv',
version='1.2.2',
description='Singer.io tap for extracting CSV files from minio',
author='rongfengliang',
url='https://github.com/rongfengliang/tap-minio-csv',
classifiers=['Programming Language :: Python :: 3 :: Only'],
py_modules=['tap_minio_csv'],
install_requires=[
'backoff==1.3.2',
'boto3==1.9.57',
'singer-encodings==0.0.3',
'singer-python==5.1.5',
'voluptuous==0.10.5'
],
extras_require={
'dev': [
'ipdb==0.11'
]
},
entry_points='''
[console_scripts]
tap-minio-csv=tap_minio_csv:main
''',
packages=['tap_minio_csv'])
- 项目包名称

发布pip 包
- 安装工具
python3 -m pip install --user --upgrade setuptools wheel twine
- 生成文件
python3 setup.py sdist bdist_wheel
- 上传
需要先注册账户,执行以下命令,按照提示输入账户信息即可
twine upload dist/*
- pip 包

说明
以上是一个简单的说明,详细代码可以参考https://github.com/rongfengliang/tap-minio-csv
参考资料
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html
https://github.com/singer-io/tap-s3-csv
https://github.com/rongfengliang/tap-minio-csv
Singer 修改tap-s3-csv 支持minio 连接的更多相关文章
- ECMall如何支持SSL连接邮件服务器的配置
首先,主要是ecmall使用的phpmailer版本太低,不支持加密连接. 然后,得对相应代码做一定调整. 1. 覆盖phpmailer 请从附件进行下载: http://files.cnblogs. ...
- 在SSIS 的 64 位版本中不支持 Excel 连接管理器
Microsoft sql server 2008 R2——> SQL SERVER Business Intelligence Development Studio 使用EXCEL数据源或目标 ...
- vs中开发web站点使IIS Express支持局域网连接
vs中开发web站点使IIS Express支持局域网连接 在开发webapi的时候,客户端设备都会使用局域网的地址访问webapi,有时候需要调试api.这个时候就需要使用一些技巧了,这里我记录了我 ...
- MySQL不支持远程连接的解决办法
如果mysql不支持远程连接,会出现提示:错误代码是1130,ERROR 1130: Host * is not allowed to connect to this MySQL server ,解决 ...
- NetworkComms V3 之支持TCP连接和UDP连接
NetworkComms V3 无缝的支持TCP连接和UDP连接. 您可以很容易的创建这两种连接 //创建一个连接信息对象 ConnectionInfo connInfo = ); //创建一个TCP ...
- Mysql 连接查询 Mysql支持的连接查询有哪些
CREATE TABLE `chx` ( `id` VARCHAR(20) NOT NULL, `name` VARCHAR(50) DEFAULT NULL, `name2` CHAR( ...
- 已使用 163 邮箱测试通过,且支持 SSL 连接。 发送邮件
示例:Jack 发送一封邮件给 Rose. public class SendMail { public static void main(String[] args) { b ...
- HslCommunication库的二次协议扩展,适配第三方通讯协议开发,基础框架支持长短连接模式
本文将使用一个gitHub开源的项目来扩展实现二次协议的开发,该项目已经搭建好了基础层架构,并实现了三菱,西门子,欧姆龙,MODBUS-TCP的通讯示例,也可以参照这些示例开发其他的通讯协议,并Pul ...
- SQLServer 2016 Express 安装部署,并配置支持远程连接
在项目中需要用到SQLServer,于是安装部署了SQLServer,部署的过程中遇到了一下问题,记录一下以便之后遇到同样问题能快速解决. 一.安装包下载 首先下载必要的安装包: 1.SQLServe ...
随机推荐
- 【转载】Linux(CentOS)下安装Redis
转载地址:https://blog.csdn.net/diweikang/article/details/78784631 1.下载Redis下载最新Linux版本的Redis,我用的是redis-4 ...
- 『选课 树形dp 输出方案』
这道题的树上分组背包的做法已经在『选课 有树形依赖的背包问题』中讲过了,本篇博客中主要讲解将多叉树转二叉树的做法,以便输出方案. 选课 Description 学校实行学分制.每门的必修课都有固定的学 ...
- UML统一建模语言介绍
统一建模语言简介 统一建模语言(Unified Modeling Language,UML)是用来设计软件蓝图的可视化建模语言,1997 年被国际对象管理组织(OMG)采纳为面向对象的建模语言的国际标 ...
- mysql 中 and和or 一起使用和之间的优先级
SELECT address,job_title,education,SUM(recruiting) FROM commerce_jobs WHERE education = '大专' and ( j ...
- c#调用python脚本实现排序(适用于python脚本中不包含第三方模块的情况)
引用:https://www.cnblogs.com/zoe-yan/p/10374757.html 利用vs2017c#调用python脚本需要安装IronPython.我是通过vs2017的工具- ...
- 《C++ Primer》学习总结;兼论如何使用'书'这种帮助性资料
6.25~ 6.27,用了3天翻了一遍<C++ Primer>. ▶书的 固有坏处 一句话: 代码比 文字描述 好看多了.————> 直接看习题部分/ 看demo就行了 看文字在描述 ...
- java面试经常涉及到的
需要掌握的Java知识点: 1 基本数据类型.循环控制.String类型的使用.数组.类和对象.接口和抽象类.面向对象三大特征.异常处理.集合类(List.Map.Set) 2 能够熟练使用Sprin ...
- Eclipse集成Git做团队开发:代码管理
在日常开发工作中,我们通常使用版本控制软件管理团队的源代码,常用的SVN.Git.与SVN相比,Git有分支的概念,可以从主分支创建开发分支,在开发分支测试没有问题之后,再合并到主分支上去,从而避免了 ...
- [ROR] 如何在mixin模块中定义类方法(Howto define class methods in a mixin module)
方法一: 修改模块的include方法 module Bbq def self.included(base) base.send :include, InstanceMethods base.exte ...
- PHP extension_loaded()用法
一.extension_loaded()函数表示检查一个扩展是否成功加载 if(!extension_loaded('sysvmsg')) { echo "Please install sy ...