Exemplo n.º 1
0
    def proc(self, context: CommandContext):
        """
        メイン処理を行います。
        context.get_rows()を呼び出して、データ行を取得しながら、
        データ加工を行ってください。

        渡されてくるデータは、イテレータの場合もあるので、次に
        引き継ぐために、context.set_rows()で、データを引き渡してください。

        """

        # 次へ引き渡す行
        rows = [row for row in context.get_rows()]
        if len(rows) == 0:
            return rows

        if type(rows[0]) == Row:
            rows = [row.raw() for row in rows]

        output_path = self.__params.output.format(**rows[0])

        # テンプレートを適用
        result = self.__template.render(rows=rows, args=self.__params.args)
        with open(output_path, 'w') as f:
            f.write(result)

        # 次のコマンドへ引渡し
        context.set_rows(rows)
Exemplo n.º 2
0
    def proc(self, context: CommandContext):
        """
        メイン処理を行います。
        context.get_rows()を呼び出して、データ行を取得しながら、
        データ加工を行ってください。

        渡されてくるデータは、イテレータの場合もあるので、次に
        引き継ぐために、context.set_rows()で、データを引き渡してください。
        """

        rows = []
        for row in context.get_rows():
            if type(row) == Row:
                rows.append(objdict(row.raw()))
            else:
                rows.append(objdict(row))

        local = {
            'input_rows': rows,
            'output_rows': [],
            'args': self.__params.args
        }

        # スクリプトの実行を行う
        try:
            exec(self.__script, self.__modules, local)
        except Exception as e:
            logger.error(e)
            raise e

        # 次のコマンドへ引渡し
        context.set_rows(local['output_rows'])
Exemplo n.º 3
0
    def proc(self, context: CommandContext):
        targets = self.__args.target_keys

        newRows = [Row(row) for row in context.get_rows()]
        if len(newRows) == 0:
            return

        rowColumns = [len(r.keys()) for r in newRows]
        index = rowColumns.index(max(rowColumns))

        if len(newRows) == 0:
            return

        if len(targets) == 0:
            targets = newRows[index].keys()

        table = prettytable.PrettyTable(targets)

        # アラインの設定
        for key in targets:
            val = newRows[0].get(key)
            table.align[key] = 'l'
            if type(val) == int:
                table.align[key] = 'r'
            if type(val) == bool:
                table.align[key] = 'c'

        for row in newRows:
            table.add_row([row.get(target) for target in targets])

        print(table)
        context.set_rows(newRows)
Exemplo n.º 4
0
    def init(self, context: CommandContext):
        # パラメータを取得する
        self.__params = context.get_parameters()
        self.__rows = []
        context.set_supplier(self)
        self.__has_data = True

        try:
            dataType = self.__params.data_type
            if dataType == 'csv':
                lines = self.__params.data.split('\n')
                head = [x.rstrip() for x in lines[0].split(',')]
                data = [line for line in lines[1:] if not line.strip() == ""]
                for row in data:
                    row = [x.rstrip() for x in row.split(',')]
                    newData = {}
                    for i in range(len(head)):
                        newData[head[i]] = row[i]
                    self.__rows.append(newData)
            if dataType == 'json':
                self.__rows = json.loads(self.__params.data)
            if dataType == 'yaml':
                self.__rows = yaml.load(self.__params.data)
            if dataType == 'object':
                if type(self.__params.data) == list:
                    self.__rows = self.__params.data
                else:
                    logger.error('データ型がlist構造になっていません')
        except Exception as e:
            logger.error(e)
            raise e
Exemplo n.º 5
0
    def proc(self, context: CommandContext):
        """
        メイン処理を行います。
        context.get_rows()を呼び出して、データ行を取得しながら、
        データ加工を行ってください。

        渡されてくるデータは、イテレータの場合もあるので、次に
        引き継ぐために、context.set_rows()で、データを引き渡してください。

        """

        # 次へ引き渡す行
        rows = []
        for row in iter(context.get_rows()):
            # Rowラッパーに変換
            row = Row(row)
            if self.__write_header == False:
                self.__write_header = True
                headers = self.__params.headers
                if len(self.__params.headers) == 0:
                    headers = row.keys()
                self.__headers = headers
                if self.__params.header:
                    self.__writer.writerow(headers)

            rows.append(row)
            # 行を追加
            self.__writer.writerow([row.get(x) for x in self.__headers])

        # 次のコマンドへ引渡し
        context.set_rows(rows)
Exemplo n.º 6
0
    def proc(self, context: CommandContext):
        rows = []

        sql = self.__params.main_sql

        # Rowラッパーに変換
        rows = []
        if self.__params.batch_count <= 0:
            # まとめてインサート
            rows = [Row(row) for row in context.get_rows()]
            if len(rows) > 0:
                self.__dbService.execute_updates(self.__cursor, sql, rows)
                self.__db.commit()
                logger.info(f"executed {len(rows)} parameters..")
        else:
            # 指定件数ずつまとめて実行
            insRows = []
            for row in context.get_rows():
                insRows.append(Row(row))
                if len(insRows) == self.__params.batch_count:
                    rows = rows + insRows
                    self.__dbService.execute_updates(self.__cursor, sql,
                                                     insRows)
                    logger.info(f"executed {len(insRows)} parameters.")
                    insRows = []

                    self.__db.commit()

            if len(insRows) > 0:
                rows = rows + insRows
                self.__dbService.execute_updates(self.__cursor, sql, insRows)
                logger.info(f"executed {len(insRows)} parameters.")

        # 次のコマンドへ引渡し
        context.set_rows(rows)
Exemplo n.º 7
0
 def init(self, context: CommandContext):
     """
     スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
     context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
     を取得することができます。
     """
     # このコマンドがデータを供給する宣言
     context.set_supplier(self)
     # フェッチサイズの指定
     self.set_fetch_size(0)
Exemplo n.º 8
0
    def init(self, context: CommandContext):
        """
        スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
        context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
        を取得することができます。
        """
        # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
        self.__params = context.get_parameters()

        # 正規表現オプションを構築
        option = 0
        for opt in self.__params.match_options:
            if opt == 'verbose':
                option |= re.VERBOSE
            elif opt == 'multiline':
                option |= re.MULTILINE
            elif opt == 'dotall':
                option |= re.DOTALL
            elif opt == 'ignore':
                option |= re.IGNORECASE

        # 正規表現をコンパイルする
        reg = re.compile(parse_easy_regexp(self.__params.pattern), option)

        self.__reg = reg
Exemplo n.º 9
0
    def init(self, context: CommandContext):
        """
        スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
        context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
        を取得することができます。
        """
        # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
        self.__params = context.get_parameters()

        # ファイルをオープンする
        logger.info(f"open file for csv write {self.__params.file_path}")
        self.__open_file = open(self.__params.file_path,
                                'w',
                                encoding=self.__params.encoding)

        # 区切り文字を決定
        delimiter = ","
        if self.__params.delimiter == "tab":
            delimiter = "\t"
        if self.__params.delimiter == "semi":
            delimiter = ";"

        # 書き込みオブジェクトを作成
        self.__writer = csv.writer(self.__open_file,
                                   delimiter=delimiter,
                                   doublequote=self.__params.doublequote,
                                   escapechar=self.__params.escape_char,
                                   quotechar=self.__params.quotechar)
        self.__write_header = False
Exemplo n.º 10
0
 def init(self, context: CommandContext):
     """
     スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
     context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
     を取得することができます。
     """
     # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
     self.__params = context.get_parameters()
Exemplo n.º 11
0
    def init(self, context: CommandContext):
        # パラメータを取得する
        self.__params = context.get_parameters()

        # データベースサービスを取得
        self.__dbService = cast(DatabaseService,
                                services.get_service('database')[0])
        # アクセスしたいDB名を指定してDBインスタンスを取得
        logger.info(f"open database {self.__params.db_name}")
        self.__db = self.__dbService.open(self.__params.db_name)
        self.__cursor = self.__dbService.cursor(self.__db)

        # 事前の処理を実施
        for sql in self.__params.init_sql.split(";"):
            sql = sql.strip()
            self.__dbService.execute(self.__cursor, sql,
                                     context.get_script_parameters())
Exemplo n.º 12
0
 def init(self, context: CommandContext):
     """
     スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
     context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
     を取得することができます。
     """
     # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
     self.__params = context.get_parameters()
     # このコマンドがデータを供給するならコメントアウト
     # context.set_supplier(self)
     self.__template = Template(self.__params.template)
Exemplo n.º 13
0
    def proc(self, context: CommandContext):
        """
        メイン処理を行います。
        context.get_rows()を呼び出して、データ行を取得しながら、
        データ加工を行ってください。

        渡されてくるデータは、イテレータの場合もあるので、次に
        引き継ぐために、context.set_rows()で、データを引き渡してください。

        """

        # 次へ引き渡す行
        rows = []
        for row in iter(context.get_rows()):
            # Rowラッパーに変換
            row = Row(row)
            print(row)
            rows.append(row)

        # 次のコマンドへ引渡し
        context.set_rows(rows)
Exemplo n.º 14
0
    def init(self, context: CommandContext):
        """
        スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
        context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
        を取得することができます。
        """
        # 親クラス呼出
        super().init(context)

        # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
        self.__params = context.get_parameters()

        # フェッチサイズを指定
        super().set_fetch_size(0)
Exemplo n.º 15
0
    def term(self, context: CommandContext):
        # 事後のSQL処理を実行
        for sql in self.__params.term_sql.split(";"):
            sql = sql.strip()
            self.__dbService.execute(self.__cursor, sql,
                                     context.get_script_parameters())
        try:
            self.__cursor.close()
        except:
            pass
        logger.info(f"close database {self.__params.db_name}")

        self.__db.commit()
        self.__db.close()
        self.__db = None
Exemplo n.º 16
0
    def init(self, context: CommandContext):
        '''
        スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
        context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
        を取得することができます。
        '''
        super().init(context)
        # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
        self.__params = context.get_parameters()
        # フェッチサイズを指定
        super().set_fetch_size(self.__params.fetch_size)

        self.__white_filters = [re.compile(x)
                                for x in self.__params.white_list]

        self.__black_filters = [re.compile(x)
                                for x in self.__params.black_list]

        self.__detector = UniversalDetector()
Exemplo n.º 17
0
    def init(self, context: CommandContext):
        """
        スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
        context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
        を取得することができます。
        """
        super().init(context)
        # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
        self.__params = context.get_parameters()
        # フェッチサイズを指定
        super().set_fetch_size(self.__params.fetch_size)

        # データベースサービスを取得
        self.__dbService = cast(DatabaseService,
                                services.get_service('database')[0])
        # アクセスしたいDB名を指定してDBインスタンスを取得
        logger.info(f"open database {self.__params.db_name}")
        self.__db = self.__dbService.open(self.__params.db_name)
        self.__cursor = self.__dbService.cursor(self.__db)
Exemplo n.º 18
0
    def init(self, context: CommandContext):
        """
        スクリプト読み込み後に、利用するコマンドの初期化時に呼び出れます。
        context.get_parameters()で、スクリプトに記述されたコマンドパラメータ
        を取得することができます。
        """
        # パラメータを取得する( self.__params.プロパティ名 でアクセス可能)
        self.__params = context.get_parameters()
        # このコマンドがデータを供給するならコメントアウト
        # context.set_supplier(self)

        modules = {}
        for key in self.__params.modules.keys():
            module_name = self.__params.modules[key]
            modules[key] = importlib.import_module(module_name)
        modules['objdict'] = objdict
        self.__modules = modules

        script = self.__params.script
        script = f'\n{script}\noutput_rows = proc(input_rows, args)'
        logger.debug(script)
        self.__script = script
Exemplo n.º 19
0
 def init(self, context: CommandContext):
     super().init(context)
     # パラメータ取得
     self.__params = context.get_parameters()
     super().set_fetch_size(self.__params.fetch_size)
Exemplo n.º 20
0
    def proc(self, context: CommandContext):
        """
        メイン処理を行います。
        context.get_rows()を呼び出して、データ行を取得しながら、
        データ加工を行ってください。

        渡されてくるデータは、イテレータの場合もあるので、次に
        引き継ぐために、context.set_rows()で、データを引き渡してください。

        """
        # 正規表現取得
        reg = self.__reg
        # マッチングターゲットキーを取得
        target_key = self.__params.target_key
        # 結果格納用のキーを取得
        match_result_key = self.__params.match_result_key
        # 出力用のフィールド
        output = self.__params.output_keys

        # 次へ引き渡す行
        rows = []
        for row in iter(context.get_rows()):
            if type(row) == dict:
                row = dict(row)
            if type(row) == Row:
                row = dict(row.raw())

            # Rowラッパーに変換
            row = Row(row)
            row.set(match_result_key, False)
            # 検索対象文字列を取得
            line = row.get(target_key)
            if line == None:
                continue

            newRow = dict(output)

            # 正規表現マッチング
            pos = None
            matchResult = reg.match(line)

            if matchResult:
                # マッチ結果を保存
                row.set(match_result_key, True)

                # グループ1の発見場所を保存
                groups = matchResult.groups()
                if len(groups) > 0:
                    pos = matchResult.start(1)

                if len(groups) > 0:
                    # 正規表現のマッチング結果を、置換します。
                    if self.__params.extract_type == 'index':
                        for key in self.__params.group_key_map:
                            index = int(self.__params.group_key_map[key])
                            newRow[key] = groups[index - 1]
                    else:
                        # ?Pで指定された正規表現のマッチ結果を抽出
                        d = matchResult.groupdict()
                        for key in d.keys():
                            newRow[key] = d[key]
            elif self.__params.skip_unmatch:
                continue

            row.set('pos', pos)

            # 結果をマージ
            for key in newRow.keys():
                row.set(key, newRow.get(key))

            rows.append(row.raw())

        # 次のコマンドへ引渡し
        context.set_rows(rows)
Exemplo n.º 21
0
def main(script_path: str, config_parameters: dict):
    context = CommandContext()
    commandList = []

    # スクリプトロード
    with open(script_path, 'r') as f:
        script = yaml.load(f, Loader=yaml.FullLoader)
        commands = script['commands']

    # スクリプトパラメータを設定
    script['parameters'].update(config_parameters)
    context.set_script_parameters(script['parameters'])

    logger.info(f"start script '{script_path}'")

    debug_mode = False
    if 'debug' in script['parameters']:
        if type(script['parameters']['debug']) == bool:
            debug_mode = script['parameters']['debug'] == True

    logger.info(f"debug mode = {debug_mode}")

    # スクリプトからコマンド群を順番に生成
    for command in commands:

        command = objdict(command)
        if debug_mode == False and command.debug == True:
            continue

        # コマンド名からコマンドインスタンスを作成
        logger.info(f"create command {command.type}")
        commandInstance = factory.new_instance(command.type, logger)

        # コマンド引数の仕様を取得する
        spec = factory.get_command_arg_spec(command.type)
        # コマンドの仕様を記述した情報からパラメータのバリデーション情報を取得
        try:
            logger.info(f'{command.type}:{command.comment}: start validate')
            argSpec = validate_spec(command.type, spec, logger)
        except Exception as e:
            logger.error(f'{command.type}:{command.comment}: {e}')

        context.set_parameterspec(argSpec)

        # 引数仕様に則ったパラメータ定義をしているか確認
        argSpec.validate(command.parameters)

        # コマンド引数を設定
        context.set_parameters(command.parameters)

        # コマンドの初期化
        logger.info(f"init command {command.type}")
        commandInstance.init(context)

        # コマンドリストへ追加
        commandList.append(commandInstance)

    # スクリプトパラメータを1行目のデータとして渡す
    context.set_rows([script['parameters']])

    # コマンド実行処理
    logger.info(f"start command loop")
    loop = 1
    while context.is_stop() == False:
        step = 1
        if loop > 1:
            context.set_rows([])

        for commandInstance in commandList:
            context.set_step(step)
            # コマンド実行
            commandInstance.proc(context)
            step += 1

        loop += 1

    # コマンド終了処理
    logger.info(f"finalize command")
    for commandInstance in commandList:
        commandInstance.term(context)

    return context
Exemplo n.º 22
0
 def proc(self, context: CommandContext):
     rows = self.__rows
     context.set_rows(rows)
     self.__has_data = False
Exemplo n.º 23
0
 def init(self, context: CommandContext):
     self.__args = context.get_parameters()
Exemplo n.º 24
0
    def proc(self, context: CommandContext):
        """
        メイン処理を行います。
        context.get_rows()を呼び出して、データ行を取得しながら、
        データ加工を行ってください。

        渡されてくるデータは、イテレータの場合もあるので、次に
        引き継ぐために、context.set_rows()で、データを引き渡してください。s
        """

        # 親データを保存
        if self.__iter_parent == None:
            self.__iter_parent = iter([row for row in context.get_rows()])
            self.__has_parent_data = True

        # 親から1行取得する
        if self.__iter_current == None:
            try:
                self.__parent_row = {}
                if self.__has_parent_data:
                    self.__parent_row = Row(next(self.__iter_parent))
            except StopIteration:
                self.__has_parent_data = False
                self.__iter_parent = None
                context.set_rows([])
                return

        if self.__iter_current == None:
            # このコマンドが提供するデータの取得処理を行う。
            # 例)ファイルをオープンして、データを読み込む
            if not self.__has_parent_data:
                self.__has_current_data = False
                context.set_rows([])
                return

            # データ取得処理
            newRows = []
            newRows = self.get_new_data(self.__parent_row)

            # 取得したデータを、未加工のまま次の処理へ
            self.__iter_current = iter(newRows)

        retRows = []
        while True:
            try:
                row = {}
                row = next(self.__iter_current)
            except StopIteration:
                self.__iter_current = None
                self.__has_current_data = False
                context.set_rows(retRows)
                return

            # 返却データを追加
            newRow = self.create_new_row(row)
            if newRow == None:
                continue

            retRows.append(newRow)

            # フェッチサイズに達したらwhileループ終了
            if self.__fetch_size > 0 and len(retRows) == self.__fetch_size:
                break

        # データを設定
        context.set_rows(retRows)