如何跟踪我在python中读入数据库的文件?

时间:2018-03-27 14:44:48

标签: python python-3.x logging mariadb

情况

我从远程数据源获取了大量的json文件。我将这些文件组织到一个存档中,然后将它们读入数据库。如有必要,存档用于重建数据库。

json文件是远程生成的,并定期发送到我的服务器,并且读入过程不断发生。不止一次,我们在一夜之间或周末对我们的服务器造成了电力损失,这对于数据库加载来说是一个巨大的问题,因为这些过程停止了,我不知道已经加载了什么以及什么没有加载#39 ;所以我不得不回滚到一些先前已知的状态并重建出档案。

要解决此问题,我的主加载程序守护程序(用python编写)现在使用logging程序包来跟踪它加载的文件。加载程序守护程序的基本工作流程是

  • cp json文件归档
  • `RM'原始
  • 将存档副本插入数据库(其MariaDB)
  • 提交数据库
  • 加载的json文件的日志文件名

我并不担心数据库中的重复,但我不想要差距;也就是说,存档中不在数据库中的东西。到目前为止,这种方法似乎可以防止出现任何差距。

对于我的日志记录,它基本上看起来像这样。守护进程启动时会收到一组收到的文件'名称,它检查已加载到目标数据库的重复项,然后加载所有非重复项。可以从我的远程数据源获取重复项。

def initialize_logs(filenames, destination)
   try:
      with open("/data/dblogs/{0}.log".format(destination), 'r') as already_used:
         seen = set([line.rstrip("\n") for line in already_used])
   except FileNotFoundError:
      print("Log file for {0} not found. Repair database".format(destination))
      quit()

   fnamelog = logging.getLogger('filename.log')
   fnamelog.setLevel(logging.INFO)
   fh = logging.FileHandler("/data/dblogs/{0}.log".format(destination))
   fh.setLevel(logging.INFO)
   fnamelog.addHandler(fh)

然后,当我处理jsonfiles时,我使用

记录添加的每个文件
fnamelog.info(filename)

数据库加载器是并行运行的,所以我最初选择了logging包来实现其内置的并发保护。有各种各样的数据库;并非每个数据库都从json文件中提取所有数据。一些信息量较多的数据库时间较短,通常为一到两个月。在这种情况下,拥有一个包含给定数据库中所有json文件的日志文件是很好的,所以如果我想在其上添加一些,我不必担心已经存在的内容,日志档案正在跟踪。

问题

一年过去了。我一直在获取json文件。我现在每月收到大约一百万个文件。处理时每个文件名的文本记录是笨拙的,但它现在仍然有效。有多个数据库,但对于最大的数据库,日志文件超过半GB。我觉得这种日志记录解决方案不会再运行得太久了。

当每个数据库有超过1000万个文件名并且正在上升时,python中有哪些选项可用于跟踪已插入数据库的文件名?

3 个答案:

答案 0 :(得分:1)

一种方法是将文件记录在数据库本身的表中而不是文本日志文件中。如果您为导入日期或文件名等添加了一些列,那么在您需要时可以为这些日志查找信息提供一点灵活性,但它也可以让您执行定期维护(如例如,如果您知道不需要查看那些日志记录,则删除超过几个月的日志记录。

如果您决定继续使用基于文本的日志文件,您可能会考虑将它们分解,以便您不会使用巨大的单片日志文件。当您安装Apache等记录大量数据的内容时,您会看到它会自动设置log rotation以定期压缩和存档日志文件...

答案 1 :(得分:1)

您没有说明您使用的数据库类型,但一般方法是

1)制作每个json文件的哈希值。 SHA256广泛可用。如果您担心效果,请参阅此帖子https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed

2)使哈希字段成为数据库中的唯一键,在执行其他操作之前,请尝试插入它。如果您不能记录已存在且事务将中止

答案 2 :(得分:0)

计划1:

Foreach file in input directory
    INSERT IGNORE into database the MD5 of the file
    "mv" the file to the archive directory

计划2,a"保持活力"程序

它每分钟都会通过cron运行并尝试启动程序1,但如果它已在运行,则不要启动它。

注意:

  • ' MV'和' cron'假设Unix。如果使用Windows,请执行等效操作。
  • ' MV'是原子的,所以文件将在另一个目录中;没有麻烦知道它是否被处理过#39; (所以,我想知道为什么你甚至有一个数据库表?)
  • 由于INSERTmv无法实际完成"原子地",这就是为什么我的计划是安全的:IGNORE
  • "它正在运行"可以通过多种方式处理,可以是程序1或2。
  • 您可以为包含md5的表添加时间戳和/或文件名;无论你喜欢什么。
  • 由于目录中甚至没有10K文件也不是一个好主意,你应该使用我想象的那对平面目录以外的东西。

每3秒钟只能获得大约1个文件。除非文件很大,否则这不是重负荷。然后它成为I / O问题,而不是数据库问题。

我有一种感觉,要么我错过了一个隐藏的要求,要么你是一个额外的偏执狂。我真的不明白你需要对这些文件做些什么。