我有一个以下形式的模型:
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。也许
所以我的问题是如何将数据保存到一列(或更多),同时保留同一行中其他列中的现有数据?
答案 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__