为什么每次迭代都会更新所有映射值?

时间:2019-08-01 09:50:48

标签: python python-3.x sqlalchemy flask-sqlalchemy

我正在尝试制作一种方法,该方法采用任意数量的sqlalchemy模型并确定它们是否具有相同的属性。该方法还采用cols_to_ignore,它是表示要忽略的列名称的字符串数组。

为此,我使用模型的属性制作了一个映射并遍历每个模型,将每个列值添加到我存储的集合中,作为映射中的值。然后将地图返回到另一种方法,该方法检查任何给定地图值的长度是否为1(表示所有属性都相同),或者不止一个含义(即所提交的模型具有不同的属性值)。

我遇到的问题是代码当前更新每个键上的值,而不只是更新具有特定列名的键。

例如,使用以下模型(在此处由json表示){birthMonth: 'January', birthYear: 1990}, {birthMonth: 'March', birthYear: 1990}运行代码应得到以下映射:

{'birthMonth':{January, March}, 'birthYear':{1990}}

但结果是:

{'birthMonth': {January,1990,March}, birthYear: {January,1990,March}}

这是我的代码:

def have_same_attributes(cols_to_ignore, *models):
    if not all_same_model(models):
        raise ValueError('Types of models must all match')
    attribute_map = dict.fromkeys(models[0].__table__.columns.keys(), set())
    for model in models:
        for key in model.__table__.columns.keys():
            if key in cols_to_ignore:
                continue
            attribute_map[key].add(getattr(model, key))
    return attribute_map
    for value in attribute_map.values():
        if(len(value)>1):
            return False
    return True

all_same_model(models)验证提交给该方法的所有模型都属于同一类型。

我觉得这很简单,我没看到,但是我已经有一段时间没碰运气了。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

这是常见[[]]*10错误的变体:dict.fromkeys使用提供的单个 object 作为每个键的值,因此只有一个{{1 }}正在更新。 (如何知道如何重新创建“类似” set对象?)

答案 1 :(得分:0)

从Davis Herring提供的答案中,我能够重构代码以避免使用dict.fromkeys方法并使它正常工作。这是现在可以使用的更新代码。

def have_same_attributes(cols_to_ignore, *models):
    if not all_same_model(models):
        raise ValueError('Types of models must all match')
    attribute_map = dict()
    for key in models[0].__table__.columns.keys():
        if key in cols_to_ignore:
            continue
        attribute_map[key] = set()
    for model in models:
        for key in model.__table__.columns.keys():
            if key in cols_to_ignore:
                continue
            attribute_map[key].add(getattr(model, key))
            if(len(attribute_map[key])>1):
                return False
    return True