将数据保存到列而不删除Django脚本中的其他数据

时间:2011-10-21 17:32:20

标签: python django

我有一个以下形式的模型:

class Data(models.Model):
    some_id = models.IntegerField(primary_key=True)
    data1 = models.IntegerField()
    data2 = models.IntegerField()
    data3 = models.CharField(max_length=150)

我正在读取各种文件中的数据,并使用标题信息来确定应保存所述文件中的列的位置。数据库中的每个列名都是唯一的,因此我也使用它们指向适当的表。

有些情况下,数据库中的给定行已经包含带有数据的列,我需要将数据添加到其他列。我在Django shell中运行python代码来执行此操作。但是,如果我为现有元素指定pk或'some_id'以将数据保存到一列中,则该行中所有其他列的数据将被覆盖为None。例如,如果我的代码是,

data_args = {}
data_args['some_id'] = 0
data_args['data2'] = 100

data_entry = Data(**data_args)

data_entry.save()

并且已填充该条目的data1和data3,在save()之后,它们将读取None。

因为我是从脚本运行它而我的列名是从标题中读取的字符串,所以我无法弄清楚如何以文档中的示例形式更新数据,例如:

data_entry = Data.objects.get(some_id=0)
data_entry.data2=100
data_entry.save()

虽然这可以从命令行工作,但是当'data2'作为文件头中的字符串读取时,它不会来自python代码。

编辑:对于缺乏清晰度表示道歉。我试图节省一些血腥的细节。当我说上面的(正确的)代码在我的脚本中不起作用时,我从文件头中访问列'data2'的名称,如下所示:

some_id|data1|data2|data3

我使用numpy.genfromtxt解析文件中的数据,它可以访问表单中数据列的名称:

data_array.dtype.names = ('some_id', 'data1', 'data2', 'data3')

因此,假设数据中的第一个条目已经存在,如果我尝试保存到没有数据的列,

single_arg = data_array.dtype.names[2]
data_entry = Data.objects.get(some_id=0)
data_entry.single_arg = 100
data_entry.save()

值100不会最终保存到第一个条目的“data2”列中。我得到的价值仍然是无。在我正在执行此操作的循环中,在save()之前,我打印出single_arg(在此示例中将显示data2),该变量包含我正在尝试分配给data_entry.single_arg的值(100 in这个例子)和data_entry.single_arg本身(在这个例子中应该读取100),它们看起来都是正确的。

但由于某种原因,该值不会保存到数据库中。如果上面的代码是正确的,那么我的问题可能就在其他地方。

进一步编辑:

正如我想的那样,问题似乎是在data_entry.single_arg中使用时,single_arg没有注册为'data2'。在save()之后,如果我重新查询数据库并尝试打印本应保存的内容:

data_entry = Data.objects.get(some_id=0)
single_arg = data_array.dtype.names[2]
print data_entry.single_arg

我收到错误:

AttributeError: 'Data' object has no attribute 'single_arg'

因此,可能是在脚本中整个字符串“data_entry.single_arg”的值为100,实际上根本没有访问对象data_entry.data2。也许

所以我的问题是如何将数据保存到一列(或更多),同时保留同一行中其他列中的现有数据?

2 个答案:

答案 0 :(得分:1)

您对getattr的属性查找感到困惑。您无法通过键入data.single_arg将字符串解析为属性 - python将如何知道是使用变量值还是属性名称?

single_arg = 'data2'
data.single_arg = 100

# you can NOT set an attribute by a string this way. 
# You're just setting an attribute called single_arg to 100 which isn't a model 
# field, so it's not going to be saved.

要通过字符串设置属性,您需要使用setattr

single_arg = 'data2'
data = Data.objects.get(id=1)
setattr(data, single_arg, 100)
data.save()

您的上一个示例符合预期。data_entry没有single_arg属性。如果您想要变量getattr(data_entry, single_arg)中引用的字符串属性,则需要调用single_arg

答案 1 :(得分:0)

你的问题的一般答案是,当你做

data_entry = Data(**data_args)
data_entry.save()

您要将新记录保存到数据库中;您未填充的任何值将获取默认值或NULL,具体取决于模型字段定义。要修改现有记录,您必须首先从数据库中检索它,就像在第二个代码块中一样:

data_entry = Data.objects.get(some_id=0) # populates data_entry object with values from db
data_entry.data2=100
data_entry.save()

如果在您的脚本中此代码似乎覆盖了您现有的值,那么还有一些其他问题在起作用。我建议在您第一次从数据库中检索时打印出对象的值,因为这可能会发现问题位于上游。打印所有模型实例值的便捷方法是:

print data_entry.__dict__