【问题标题】:Saving data to a column without deleting others in a Django script将数据保存到列而不删除 Django 脚本中的其他列
【发布时间】:2023-03-30 01:44:02
【问题描述】:

我有一个形式为:

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”以将数据保存到一列中,则该行中所有其他列的数据将被覆盖为无。例如,如果我的代码读取,

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')

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

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 实际上根本没有被访问。也许吧。

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

【问题讨论】:

  • 当你说“当'data2'被从文件头读取为字符串时”是什么意思?你能举一个这样做的代码的例子吗?正如 Dave 和 Brian 所说,您的第二个示例是正确的,所以问题一定出在其他地方。

标签: python django


【解决方案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 属性。如果要在变量single_arg 中引用字符串属性,则需要调用getattr(data_entry, single_arg)

【讨论】:

  • 谢谢。这就是我一直在寻找的。​​span>
  • 我很高兴它有帮助。我试图理解这个“single_arg”是什么......然后它击中了我你想要做的事情。
【解决方案2】:

您的问题的一般答案是当您这样做时

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__

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    • 2018-03-24
    相关资源
    最近更新 更多