1

我正在使用一个名为 bonobo 的轻型 ETL 库。csv writer bonobo.CsvWriter 类有一个工厂方法:

def writer_factory(self, file):
        return csv.writer(file, **self.get_dialect_kwargs()).writerow

与文档:

class CsvWriter(FileWriter, CsvHandler):
    @Method(
        __doc__='''
            Builds the CSV writer, a.k.a an object we can pass a field collection to be written as one line in the
            target file.

            Defaults to builtin csv.writer(...).writerow, but can be overriden to fit your special needs.
        '''
    )

我想添加一些额外的参数来自定义我的 csv 文件,所以我尝试这样覆盖它:

class quoCsvWriter(bonobo.CsvWriter):    
def writer_factory(self, file):
            return csv.writer(file, **self.get_dialect_kwargs(),quoting=csv.QUOTE_NONNUMERIC).writerow

当我将节点添加到链中时,程序显示:

Traceback (most recent call last):
  File "geocoding.py", line 162, in <module>
    get_graph(),
  File "geocoding.py", line 135, in get_graph
    quoCsvWriter('db_addresses.csv')
  File "/Users/xxxx/xxxx/lib/python3.6/site-packages/bonobo/config/configurables.py", line 152, in __new__
    missing.remove(name)
KeyError: 'writer_factory'

任何提示表示赞赏。

更新:

与此同时,当我尝试做

bonobo.CsvWriter('filename.csv',quoting=csv.QUOTE_MINIMAL)

它抛出错误:

TypeError  "quoting" must be an integer
4

1 回答 1

2

从 bonobo 0.6 开始,在子类中直接覆盖 Method 实例并非易事。相反,您应该在构造函数参数中提供覆盖的实现。

def writer_factory(self, file):
    return csv.writer(file, **{**self.get_dialect_kwargs(), 'quoting': csv.QUOTE_NONNUMERIC}).writerow

def get_graph(**options):
    graph = bonobo.Graph()
    graph.add_chain(
      extract,
      bonobo.CsvWriter('...', writer_factory=writer_factory),

    )

    return graph

如果你真的想为这个用例子类化,你可以通过覆盖get_dialect_kwargs()方法来做到这一点:

@use_context
class QuoteNonNumericCsvWriter(bonobo.CsvWriter):
    def get_dialect_kwargs(self):
        return {
            **super().get_dialect_kwargs(),
            'quoting': csv.QUOTE_NONNUMERIC,
        }

这应该按预期工作。

当然,quoting从 bonobo 0.6.2 开始,可以直接从编写器构造函数覆盖,之前有一个错误,但现在已发布修复。

def get_graph(**options):
    graph = bonobo.Graph()
    graph.add_chain(
      extract,
      bonobo.CsvWriter('...', quoting=csv.QUOTE_NONNUMERIC),
    )

所有三种方法都有完全相同的行为,你应该支持最后一种。

希望有帮助。

于 2018-03-29T10:01:27.427 回答