0

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

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

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

4

4 回答 4

1

有没有办法维护“最后一次修改”字段?这就是您真正想要的:基于上次运行备份的增量备份,与上次更改/删除(/添加)对象的时间相比。

于 2009-06-19T18:25:21.780 回答
1

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

至于你对交叉点的想法......应该反之亦然!您必须将所有数据从 CSV 导入临时表,并在 2 个 SQL 数据库表之间进行交集。如果您使用 Oracle 或 MS SQL 2008(不确定是否适用于 2005),您会发现一个非常有用的 MERGE 关键字,因此您可以更轻松地编写 SQL,然后您将花费在其他编程语言中合并数据。

于 2009-06-19T18:33:05.620 回答
1

处理大量数据的标准方法就是这样。

我们假设 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 可以累积在一个保持排序的结构中,那么可以节省大量时间。

对冗长感到抱歉,但您需要知道哪个迭代器引发了StopIteration,因此您不能(简单地)将整个 while 循环包装在一个大的旧 try 块中。

于 2009-06-19T19:11:13.027 回答
0

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

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

于 2009-06-19T18:26:18.063 回答