Source code for lodstorage.csv
import csv
import io
from lodstorage.jsonable import JSONAble
from lodstorage.lod import LOD
[docs]
class CSV(LOD):
"""
helper for converting data in csv format to list of dicts (LoD) and vice versa
"""
[docs]
@staticmethod
def restoreFromCSVFile(
filePath: str, headerNames: list = None, withPostfix: bool = False
):
"""
restore LOD from given csv file
Args:
filePath(str): file name
headerNames(list): Names of the headers that should be used. If None it is assumed that the header is given.
withPostfix(bool): If False the file type is appended to given filePath. Otherwise file type MUST be given with filePath.
Returns:
list of dicts (LoD) containing the content of the given csv file
"""
if not withPostfix:
filePath += ".csv"
csvStr = CSV.readFile(filePath)
lod = CSV.fromCSV(csvStr, headerNames)
return lod
[docs]
@staticmethod
def fromCSV(
csvString: str,
fields: list = None,
delimiter=",",
quoting=csv.QUOTE_NONNUMERIC,
**kwargs
):
"""
convert given csv string to list of dicts (LOD)
Args:
csvStr(str): csv string that should be converted to LOD
headerNames(list): Names of the headers that should be used. If None it is assumed that the header is given.
Returns:
list of dicts (LoD) containing the content of the given csv string
"""
csvStream = io.StringIO(csvString)
reader = csv.DictReader(
csvStream, fieldnames=fields, delimiter=delimiter, quoting=quoting, **kwargs
)
lod = list(reader)
CSV.fixTypes(lod)
return lod
[docs]
@staticmethod
def storeToCSVFile(lod: list, filePath: str, withPostfix: bool = False):
"""
converts the given lod to CSV file.
Args:
lod(list): lod that should be converted to csv file
filePath(str): file name the csv should be stored to
withPostfix(bool): If False the file type is appended to given filePath. Otherwise file type MUST be given with filePath.
Returns:
csv string of the given lod
"""
if not withPostfix:
filePath += ".csv"
csvStr = CSV.toCSV(lod)
CSV.writeFile(csvStr, filePath)
[docs]
@staticmethod
def toCSV(
lod: list,
includeFields: list = None,
excludeFields: list = None,
delimiter=",",
quoting=csv.QUOTE_NONNUMERIC,
**kwargs
):
"""
converts the given lod to CSV string.
For details about the csv dialect parameters see https://docs.python.org/3/library/csv.html#csv-fmt-params
Args:
lod(list): lod that should be converted to csv string
includeFields(list): list of fields that should be included in the csv (positive list)
excludeFields(list): list of fields that should be excluded from the csv (negative list)
kwargs: csv dialect parameters
Returns:
csv string of the given lod
"""
if lod is None:
return ""
if isinstance(lod[0], JSONAble):
lod = [vars(d) for d in lod]
if excludeFields is not None:
lod = LOD.filterFields(lod, excludeFields)
if includeFields is None:
fields = LOD.getFields(lod)
else:
fields = includeFields
lod = LOD.filterFields(lod, includeFields, reverse=True)
csvStream = io.StringIO()
dict_writer = csv.DictWriter(
csvStream, fieldnames=fields, delimiter=delimiter, quoting=quoting, **kwargs
)
dict_writer.writeheader()
dict_writer.writerows(lod)
csvString = csvStream.getvalue()
return csvString
[docs]
@staticmethod
def readFile(filename: str) -> str:
"""
Reads the given filename and returns it as string
Args:
filename: Name of the file that should be returned as string
Returns:
Content of the file as string
"""
with open(filename, "r") as file:
content = file.read()
return content
[docs]
@staticmethod
def writeFile(content: str, filename: str) -> str:
"""
Write the given str to the given filename
Args:
content(str): string that should be written into the file
filename: Name of the file the given str should be written to
Returns:
Nothing
"""
with open(filename, "w") as file:
file.write(content)
[docs]
@staticmethod
def fixTypes(lod: list):
"""
fixes the types of the given LoD.
"""
for record in lod:
for key, value in record.items():
# fix empty csv value: "cell1,,cell3" converts the second value to empty string instead of None
if value == "":
record[key] = None