Django bulk_create()不存在ForeignKey

yxyvkwin  于 2023-11-20  发布在  Go
关注(0)|答案(2)|浏览(186)

我有2个模型。为了简单起见,我删除了所有不必要的字段。

class User(models.Model):
    id = models.CharField(max_length=36, primary_key=True, null=False)
    age = models.IntegerFiels(default=-1)

字符串

class Device(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)


通过API,我接收有关设备的信息并创建一个设备列表。

devices = []
for device_data in data:
    devices.append(
        Device(
            user_id=device_data("user_id")
        )
    )


一旦我有了设备列表,我就把它添加到数据库中。

Device.objects.bulk_create(devices, ignore_conflicts=True)


问题是,如果在创建设备时,我指定了一个不在数据库中的user_id,我会崩溃,因为我试图链接一个不存在的id。
现在,为了解决这个问题,我做以下事情:

devices = []
users = []
for device_data in data:
    users.append(
        User(
            id=device_data("user_id", age = -1)
        )
    )
    devices.append(
        Device(
            user_id=device_data("user_id")
        )
    )


然后,在保存时:

User.objects.bulk_create(users, ignore_conflicts=True)
Device.objects.bulk_create(devices, ignore_conflicts=True)
User.objects.filter(age=-1).delete()


如何确保在保存时,如果指定的user_id不存在,则不会添加此设备?

已删除:

另一个解决办法是换场

User.age = models.IntegerFiels(null=True)


Device.user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)


在此之后,我可以保存设备没有用户。

Device.objects.bulk_create(devices, ignore_conflicts=True)


然后执行:Device.objects.filter(user__age__isnull=True).delete()
这是可行的,但我不喜欢你需要检查年龄,而不是用户本身。

kqlmhetl

kqlmhetl1#

问题是,如果在创建设备时,我指定了一个不在数据库中的user_id,我会崩溃,因为我试图链接一个不存在的id。
如果您不希望您的设备需要用户,请将ForeignKey设置为可空:

class Device(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=true)

字符串

更新

哦,我误解了。你想只批量创建那些有现有用户ID的设备?为什么不过滤掉有可用user_id的设备数据呢?

devices = []
user_ids = User.objects.values_list("id", flat=True)
# assuming that device_data is a dictionary
for device_data in data:
    if "user_id" in device_data and device_data["user_id"] in user_ids:
        devices.append(Device(**device_data))

aydmsdu9

aydmsdu92#

我有几个建议给你
1 -应用查询以检查用户是否存在

devices = []
for device_data in data:
user_id = device_data.get("user_id")  # Use get() to avoid KeyError if user_id is not present
if User.objects.filter(id=user_id).exists():
    device = Device(user_id=user_id)
    devices.append(device)

字符串

如果你有一个大数据,这将是昂贵的操作

2 -使用简单的for循环将Try Catch块应用于非批量操作,如果满足系统要求,您可以使用后台任务来改进它
3 -当你从API获取数据时,如果你可以只获取公共值,请应用过滤器
4 -使设备模型中的用户接受默认值,如果没有数据,则将其作为默认值,这样,如果您需要在功能中分析它,则可以保留所有数据,并且您可以控制如何使用过滤器获取它

相关问题