python将指定格式文件读取,存储到数据库中

本文介绍了一种批量导入指定格式的.def文件至MongoDB数据库的方法,通过Python脚本实现文件读取、解析和存储,支持文件后缀及格式的扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本案例是,在工作中的实际需求,基于基本框架实现的, import中引入了很多框架封装好的组件,不能直接使用,课参考实现的一些开发思路。

需求: 将指定path下(包含子目录)的指定文件后缀和指定格式的文件内容,存储到数据库中,并能扩展其他文件后缀和其他格式的内容。

开发环境:python3.8 + JDK1.8 + MongoDB

分析:

1、分析需求:1)文件读取。2)写入数据库。3)导入文件的格式易扩展。
2、指定格式的 .def 文件导入到MongoDB指定的表单中。新建import_file.py , import_file2db.py 。
     1)、import_file.py文件
        定义基类 FileResources,执行对文件的相关操作:
            a、遍历path下的文件列表    b、获取文件名   c、获取文件数据。
        定义类 DefFileResources 继承 FileResources,执行 def 文件数据的格式化处理。
     2)、import_file2db.py文件
      定义基类 ImportDB ,初始化 dash, db_info , trace
      定义类 ImportMessageFormat 继承 ImportDB , 将 .def 文件的内容保存或更新到数据库message_format中
3、扩展功能:
     定义新类  newFileResources 继承  FileResources  ,执行 新格式文件数据的格式化处理。
     定义新类  newImport 继承 ImportDB ,将新格式文件数据保存到相关数据库表单中。

 

文件格式:

1、文件名:  xx.def

2、内容格式:

##  {dbName=None, version=1, collection=message_format}  ##
""""""
DHCP: binary, big_endian {
    Op: byte, valueIn(1, 2, 3, 4, 5, 6), value(0x01);
    Htype: byte, value(0x01);
    Hlen: byte, valueRange(0, 16), value(0x06);
    Hops: byte, value(0x00);
    Xid: word, value(0x7b7c7b65);
    Secs: word, value(0x0000);
    Flags: word, value(0x8000);

""""""

import_file.py文件

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : import_file.py
# @Author: lianggl
# @Time  : 2020/6/30 10:26
import os
import re
from base.xdashboard import xDashboard, xTrace
from dbrw.import_file2db import ImportMessageFormat
from py_env import PyEnv
class FileResources(object):
    """
    对文件的相关操作
    1、遍历path下的文件列表
    2、获取文件名
    3、获取文件数据
    """

    def __init__(self, path, filters, trace=None):
        self.path = path
        self.filters = filters
        if trace:
            self.trace = trace
        else:
            self.trace = xTrace()

    def scan_dir(self):
        """
        获取指定path下,后缀名为 filters 的文件列表
        :param path: 文件所在目录
        :param filters: 文件后缀
        :return: 特定后缀名的文件名list
        """
        # 获取指定目录的绝对路径
        target_path = os.path.join(PyEnv.cur_dir(), self.path)
        self.trace.info(f'target_path: {target_path}')
        filesList = []
        if target_path:
            # 遍历路径下, 后缀为指定 filters 的文件
            for root, dirs, files in os.walk(target_path):
                if not files:
                    continue
                for file in files:
                    if os.path.splitext(file)[1] == self.filters:
                        filesList.append(os.path.join(root, file))
                        # filesList.append(file)
            self.trace.info(f'filesList: {filesList}')
        else:
            self.trace.warning(f'Should spectify a relative path based on the root directory !')

        return filesList

    def get_file_name(self, file):
        if file:
            baseName = os.path.basename(file)
            self.trace.info(f'FileName is : {os.path.splitext(baseName)[0]}')
            return os.path.splitext(baseName)[0]

    def get_file_data(self, file):
        if file:
            with open(file, 'r', encoding='UTF-8') as f:
                fileData = f.read()
            self.trace.info(f'FileData is : {fileData}')
        return fileData


class DefFileResources(FileResources):
    """
    导入 .def 文件
    1、转换 def 文件的 header为 Dict
    2、转换 def 文件的 fileData 为 Dict
    3、调用类 ImportMessageFormat 实现文件写入 DB
    """

    def __init__(self, path, filters='.def'):
        """
        初始化 dash , trace
        """
        super().__init__(path, filters)
        self.dash = xDashboard(task_name='importFiles', create_mq=False)
        self.trace = self.dash.trace

    def fetch_file(self, file):
        """
        格式化header data 为 message_format 表单格式
        :param file:
        :return:  message_format表单的数据格式
        """
        docDict = {}
        fileName = self.get_file_name(file)
        docDict['fileName'] = fileName
        strBuffer = self.get_file_data(file)

        header = re.findall('\#\#[\s]*\{[\s\S]*\}[\s]*\#\#', strBuffer)
        self.trace.info(f'File Header : {header}')
        if header:
            headerDict = self.visitHeader(header)
            docDict['headerDict'] = headerDict
        else:
            self.trace.warning(f'Irregular header information: "" ... "" ')

        fileData = re.findall('\"{6}[\s]*[\s\S]*[\s]*\"{6}', strBuffer)
        if fileData:
            fileDataDict = self.visitFileData(fileData)
            docDict['fileData'] = fileDataDict
        return docDict

    # 格式化fileData
    def visitFileData(self, fileData):
        self.trace.info(f'File Data: {fileData}')
        if isinstance(fileData, list):
            result = fileData[0].strip()
            rstData = result.strip('\n')[6:-6]
            self.trace.info(f'File Data : {rstData}')
            return rstData

    # 格式化header
    def visitHeader(self, header):
        if isinstance(header, list):
            result = self.removeWhiteSpace(header[0])
            rstDict = self.convert2Dict(result[2:-2])
        return rstDict

    # 格式化header信息
    def removeWhiteSpace(self, str):
        result = str.strip()
        result = result.strip('\n')
        result = result.replace(' ', '')
        result = result.replace('\r', '')
        result = result.replace('\n', '')
        return result

    # 转为dict格式
    def convert2Dict(self,str):
        # {dbname = None, version = 1, collection =dict}
        self.trace.info(str)
        valueDict = dict()
        if re.search('^\{[\s\S]*\}$', str):
            str = str[1:-1]
            map = str.split(',')
            self.trace.info(map)
            for i in map:
                kv = i.split('=')
                self.trace.info(kv)
                valueDict[kv[0]] = kv[1]
            return valueDict

    def import_message_format(self):
        """
        将path目录下的 .def 文件导入到数据库 message_format 表单中
        :param path: 文件所在的路径
        :param filters: .def 文件后缀
        :return: 是否成功
        """
        importMessageFormat = ImportMessageFormat(self.dash, self.trace)

        # count统计文件总数,count_success统计成功的数量
        count = 0
        count_success = 0

        filesList = self.scan_dir()
        if len(filesList) > 0:
            count = len(filesList)
            for file in filesList:
                docDict = self.fetch_file(file)
                if importMessageFormat.save_data(docDict):
                    count_success += 1
        else:
            self.trace.info(f'File list is empty,Please check if the path parameters are correct, \
                or Whether there is a .def file .')
        self.dump_result(count, count_success)
        return None

    # 导入 .def 文件结果统计
    def dump_result(self, count, count_success):
        self.trace.info(f'*' * 50)
        self.trace.info(f'Total : {count} , Success : {count_success} , Error : {count - count_success}')
        self.trace.info(f'*' * 50)
        return None


if __name__ == '__main__':
    # .def 文件须在 path 下
    defFileResources = DefFileResources(path='smoketest/test', filters='.def')
    defFileResources.import_message_format()

 

import_file2db.py文件:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : import_file2db.py
# @Author: lianggl
# @Time  : 2020/6/30 10:50
from apis.protocol.parser.form.form_parser import ProtocolFormParser
from base.xdashboard import xTrace
from database.db_backup_inf import DBWriter


class ImportDB(object):
    """
    将指定格式的数据写入到数据库中相应的表单中,执行save/update操作
    """

    def __init__(self, dash, trace):
        self.dash = dash
        self.db_info = DBWriter(self.dash.db.client)
        if trace:
            self.trace = trace
        else:
            self.trace = xTrace()

    def save_data(self, docDict):
        pass


class ImportMessageFormat(ImportDB):
    """
    将 .def 文件的内容,save/update 到数据库的message_format表单中
    """

    def __init__(self, dash, trace):
        super().__init__(dash, trace)

    def save_data(self, docDict):

        fileName = docDict['fileName']
        dbName = docDict['headerDict']['dbName']
        collection = docDict['headerDict']['collection']
        pcode = docDict['fileData']

        try:
            jcode = ProtocolFormParser(debug=False).parse_doc(pcode).data
            doc = dict(name=fileName, pcode=pcode, jcode=jcode, desc='', proto_filter=list())
            self.db_info.insert_update_one(dict(name=fileName), doc, collection)
            self.trace.info(f'File {fileName} save or update Success !!')
            return True

        except Exception as e:
            self.trace.warning(e)
            return False
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值