我有一个数据源,它提供了一个对象及其属性列表(一个CSV文件,但这没关系)。每次我的程序运行时,它都需要提取对象列表的新副本,将其与存储在数据库中的对象列表(及其属性)进行比较,并根据需要更新数据库。

处理新对象很容易 - 数据源为每个对象提供一个顺序ID号,在数据库的新信息中检查顶部ID号,然后就完成了。我正在寻找其他情况的建议 - 一些对象的属性发生了变化,或者某个对象被删除了。

一个天真的解决方案是从数据库中提取所有对象并获得两个集合(旧的和新的)的交集的补充,然后检查这些结果,但是这似乎不会非常有效集合变大。有什么想法吗?

有帮助吗?

解决方案

大量数据的标准方法相当于此。

我们假设list_1是“主人”。 (没有重复)和list_2是“更新”和“更新”。这可能有重复。

iter_1 = iter( sorted(list_1) ) # Essentially SELECT...ORDER BY
iter_2 = iter( sorted(list_2) )
eof_1 = False
eof_2 = False
try:
    item_1 = iter_1.next()
except StopIteration:
    eof_1= True
try:
    item_2 = iter_2.next()
except StopIteration:
    eof_2= True
while not eof_1 and not eof_2:
    if item_1 == item_2:
        # do your update to create the new master list.
        try:
            item_2 = iter_2.next()
        except StopIteration:
            eof_2= True
    elif item_1 < item_2:
        try:
            item_1 = iter_1.next()
        except StopIteration:
            eof_1= True
    elif item_2 < item_1:
        # Do your insert to create the new master list.
        try:
            item_2 = iter_2.next()
        except StopIteration:
            eof_2= True
assert eof_1 or eof_2
if eof_1:
    # item_2 and the rest of list_2 are inserts.
elif eof_2:
    pass
else:
    raise Error("What!?!?") 

是的,它涉及潜在的排序。如果list_1在将其写回文件系统时按排序顺序保留,则可节省大量时间。如果list_2可以在一个保持排序的结构中累积,那么可以节省大量时间。

对于wordiness抱歉,但你需要知道哪个迭代器引发了 StopIteration ,所以你不能(通常)将整个while循环包装在一个很旧的try块中。

其他提示

没有办法维持“最后一次修改”吗?领域?这就是你真正想要的东西:基于上次运行备份的增量备份,与上次更改/删除(/添加)对象相比。

您需要在数据库和CSV文件中都有时间戳。时间戳应该在记录更新时显示数据,您应该将记录的时间戳与相同的ID进行比较,以确定是否需要更新记录

关于交叉的想法... 应该这样做反之亦然! 您必须将所有数据从CSV导入临时表,并在两个SQL数据库表之间进行交集。如果您使用Oracle或MS SQL 2008(2005年不确定),您将找到一个非常有用的MERGE关键字,因此您可以用较少的努力编写SQL,然后花费在其他编程语言中合并数据。

当您将列表拉入程序时,根据数据库表中的列属性迭代列表,执行查询,该列属性从ObjectName列表中映射到对象的相同属性。或者您可以将整个表加载到列表中并以此方式比较列表。我假设你对除了数据库分配的ID之外存在的对象有一些独特的东西。

如果通过查询未在表中找到该对象,请创建一个新条目。如果发现它像FogleBird一样,那么在表格中为该对象存储计算的散列或CRC,您可以将其与列表中的对象进行比较(在对象上运行计算)。如果散列不匹配,请使用列表中的对象更新该对象。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top