feat: ローカルファイル書き込み用モジュールを追加
This commit is contained in:
parent
59e9c2e8a7
commit
5cfcd0e3e5
@ -61,6 +61,7 @@ class CSVStringConverter:
|
|||||||
f'CSV変換に失敗しました カラム名:[{column}] 行番号: [{i}] エラー内容:[{e}]')
|
f'CSV変換に失敗しました カラム名:[{column}] 行番号: [{i}] エラー内容:[{e}]')
|
||||||
|
|
||||||
def __write_csv_string(self, csv_data) -> str:
|
def __write_csv_string(self, csv_data) -> str:
|
||||||
|
# TODO: CsvWriterに移管
|
||||||
try:
|
try:
|
||||||
with io.StringIO(newline='') as string_stream:
|
with io.StringIO(newline='') as string_stream:
|
||||||
writer = csv.writer(string_stream, delimiter=',', lineterminator='\r\n',
|
writer = csv.writer(string_stream, delimiter=',', lineterminator='\r\n',
|
||||||
|
|||||||
@ -72,11 +72,20 @@ UPLD_JP_NAME = 'CSVアップロード処理'
|
|||||||
UPD_JP_NAME = '前回取得日時ファイル更新'
|
UPD_JP_NAME = '前回取得日時ファイル更新'
|
||||||
END_JP_NAME = '取得処理実施結果アップロード処理'
|
END_JP_NAME = '取得処理実施結果アップロード処理'
|
||||||
|
|
||||||
# CSVチェック
|
# CSV
|
||||||
CSV_TRUE_VALUE = 1
|
CSV_TRUE_VALUE = 1
|
||||||
CSV_FALSE_VALUE = 0
|
CSV_FALSE_VALUE = 0
|
||||||
|
CSV_LINE_TERMINATOR = '\r\n'
|
||||||
|
CSV_DELIMITER = ','
|
||||||
|
CSV_QUOTE_CHAR = '"'
|
||||||
|
|
||||||
# オブジェクト変数
|
# システム変数
|
||||||
|
|
||||||
|
FILE_CHAR_CODE = 'utf-8'
|
||||||
|
FILE_MODE_WRITE = 'w'
|
||||||
|
|
||||||
|
|
||||||
|
# CRM_取得オブジェクト情報ファイル関連
|
||||||
OBJECTS_KEY = 'objects'
|
OBJECTS_KEY = 'objects'
|
||||||
OBJECTS_TYPE = list
|
OBJECTS_TYPE = list
|
||||||
OBJECT_NAME_KEY = 'object_name'
|
OBJECT_NAME_KEY = 'object_name'
|
||||||
@ -94,6 +103,8 @@ UPLOAD_FILE_NAME_TYPE = str
|
|||||||
DATETIME_COLUMN_KEY = 'datetime_column'
|
DATETIME_COLUMN_KEY = 'datetime_column'
|
||||||
DATETIME_COLUMN_TYPE = str
|
DATETIME_COLUMN_TYPE = str
|
||||||
DATETIME_COLUMN_DEFAULT_VALUE = 'SystemModstamp'
|
DATETIME_COLUMN_DEFAULT_VALUE = 'SystemModstamp'
|
||||||
|
|
||||||
|
# 前回取得日時ファイル関連
|
||||||
LAST_FETCH_DATETIME_TO_KEY = 'last_fetch_datetime_to'
|
LAST_FETCH_DATETIME_TO_KEY = 'last_fetch_datetime_to'
|
||||||
LAST_FETCH_DATETIME_TO_TYPE = str
|
LAST_FETCH_DATETIME_TO_TYPE = str
|
||||||
LAST_FETCH_DATETIME_FROM_KEY = 'last_fetch_datetime_from'
|
LAST_FETCH_DATETIME_FROM_KEY = 'last_fetch_datetime_from'
|
||||||
|
|||||||
0
ecs/crm-datafetch/src/writer/__init__.py
Normal file
0
ecs/crm-datafetch/src/writer/__init__.py
Normal file
43
ecs/crm-datafetch/src/writer/file_writer.py
Normal file
43
ecs/crm-datafetch/src/writer/file_writer.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import csv
|
||||||
|
import json
|
||||||
|
from abc import ABCMeta, abstractmethod
|
||||||
|
|
||||||
|
from src.system_var.constants import (CSV_DELIMITER, CSV_LINE_TERMINATOR,
|
||||||
|
CSV_QUOTE_CHAR, FILE_CHAR_CODE,
|
||||||
|
FILE_MODE_WRITE)
|
||||||
|
|
||||||
|
|
||||||
|
class FileWriter(metaclass=ABCMeta):
|
||||||
|
|
||||||
|
def __init__(self, file_path: str, content) -> None:
|
||||||
|
self._file_path = file_path
|
||||||
|
self._content = content
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def write(self) -> str:
|
||||||
|
"""ファイルを書き出し、ファイルパスを返す
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: 書き出し先のファイルパス
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class JsonWriter(FileWriter):
|
||||||
|
|
||||||
|
def write(self) -> str:
|
||||||
|
with open(self._file_path, mode=FILE_MODE_WRITE, encoding=FILE_CHAR_CODE, newline='') as f:
|
||||||
|
json.dump(self._content, f, ensure_ascii=False, )
|
||||||
|
|
||||||
|
return self._file_path
|
||||||
|
|
||||||
|
|
||||||
|
class CsvWriter(FileWriter):
|
||||||
|
|
||||||
|
def write(self) -> str:
|
||||||
|
with open(self._file_path, mode=FILE_MODE_WRITE, encoding=FILE_CHAR_CODE, newline='') as f:
|
||||||
|
writer = csv.writer(f, delimiter=CSV_DELIMITER, lineterminator=CSV_LINE_TERMINATOR,
|
||||||
|
quotechar=CSV_QUOTE_CHAR, doublequote=True, quoting=csv.QUOTE_ALL,
|
||||||
|
strict=True)
|
||||||
|
writer.writerows(self._content)
|
||||||
|
return self._file_path
|
||||||
0
ecs/crm-datafetch/tests/writer/__init__.py
Normal file
0
ecs/crm-datafetch/tests/writer/__init__.py
Normal file
110
ecs/crm-datafetch/tests/writer/test_file_writer.py
Normal file
110
ecs/crm-datafetch/tests/writer/test_file_writer.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import os
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from src.writer.file_writer import CsvWriter, JsonWriter
|
||||||
|
|
||||||
|
|
||||||
|
class TestJsonFileWriter:
|
||||||
|
|
||||||
|
def test_write(self, tmpdir):
|
||||||
|
"""
|
||||||
|
Cases:
|
||||||
|
JSONファイルが書き込めること
|
||||||
|
Arranges:
|
||||||
|
|
||||||
|
Expects:
|
||||||
|
JSONファイルが正しく書き込まれている
|
||||||
|
"""
|
||||||
|
# Arrange
|
||||||
|
file_name = 'test.json'
|
||||||
|
file_path = os.path.join(tmpdir, file_name)
|
||||||
|
content = {'test': 'テスト'}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
sut = JsonWriter(file_path, content)
|
||||||
|
sut.write()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
with open(file_path) as f:
|
||||||
|
actual = f.read()
|
||||||
|
|
||||||
|
assert actual == '{"test": "テスト"}'
|
||||||
|
|
||||||
|
def test_raise_write_cause_file_path_not_exists(self):
|
||||||
|
"""
|
||||||
|
Cases:
|
||||||
|
書き込み先が存在しない場合エラーとなること
|
||||||
|
Arranges:
|
||||||
|
|
||||||
|
Expects:
|
||||||
|
エラーが発生する
|
||||||
|
"""
|
||||||
|
# Arrange
|
||||||
|
file_name = 'test.json'
|
||||||
|
file_path = os.path.join('invalid', file_name)
|
||||||
|
content = {'test': 'テスト'}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
sut = JsonWriter(file_path, content)
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
sut.write()
|
||||||
|
|
||||||
|
|
||||||
|
class TestCsvFileWriter:
|
||||||
|
|
||||||
|
def test_write(self, tmpdir):
|
||||||
|
"""
|
||||||
|
Cases:
|
||||||
|
CSVファイルが書き込めること
|
||||||
|
Arranges:
|
||||||
|
|
||||||
|
Expects:
|
||||||
|
CSVファイルが正しく書き込まれている
|
||||||
|
"""
|
||||||
|
# Arrange
|
||||||
|
file_name = 'test.csv'
|
||||||
|
file_path = os.path.join(tmpdir, file_name)
|
||||||
|
content = [
|
||||||
|
["Id", "AccountId", "UserOrGroupId", "AccountAccessLevel", "OpportunityAccessLevel", "CaseAccessLevel",
|
||||||
|
"ContactAccessLevel", "RowCause", "LastModifiedDate", "LastModifiedById", "IsDeleted"],
|
||||||
|
["TEST001", "test001", "", "1", "2", "3", "4", "テストのため1", "2022-06-01 09:00:00", "1234567.0", "0"],
|
||||||
|
["TEST002", "test002", "", "5", "6", "7", "8", "テストのため2", "2022-06-03 01:30:30", "2.23", "1"],
|
||||||
|
["TEST003", "test003", "", "9", "10", "11", "12", "テストのため3", "2022-06-04 08:50:50", "3.234567", "0"]
|
||||||
|
]
|
||||||
|
|
||||||
|
# Act
|
||||||
|
sut = CsvWriter(file_path, content)
|
||||||
|
sut.write()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
with open(file_path, newline='') as f:
|
||||||
|
actual = f.read()
|
||||||
|
|
||||||
|
expect = """\
|
||||||
|
"Id","AccountId","UserOrGroupId","AccountAccessLevel","OpportunityAccessLevel","CaseAccessLevel","ContactAccessLevel","RowCause","LastModifiedDate","LastModifiedById","IsDeleted"\r\n\
|
||||||
|
"TEST001","test001","","1","2","3","4","テストのため1","2022-06-01 09:00:00","1234567.0","0"\r\n\
|
||||||
|
"TEST002","test002","","5","6","7","8","テストのため2","2022-06-03 01:30:30","2.23","1"\r\n\
|
||||||
|
"TEST003","test003","","9","10","11","12","テストのため3","2022-06-04 08:50:50","3.234567","0"\r\n\
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert actual == textwrap.dedent(expect)
|
||||||
|
|
||||||
|
def test_raise_write_cause_file_path_not_exists(self):
|
||||||
|
"""
|
||||||
|
Cases:
|
||||||
|
書き込み先が存在しない場合エラーとなること
|
||||||
|
Arranges:
|
||||||
|
|
||||||
|
Expects:
|
||||||
|
エラーが発生する
|
||||||
|
"""
|
||||||
|
# Arrange
|
||||||
|
file_name = 'test.csv'
|
||||||
|
file_path = os.path.join('invalid', file_name)
|
||||||
|
content = {'test': 'テスト'}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
sut = CsvWriter(file_path, content)
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
sut.write()
|
||||||
Loading…
x
Reference in New Issue
Block a user