3

使用 pandas to_sql 函数时有没有办法插入外键?

在将它们添加到数据库(postgres)之前,我正在Consultation使用 django 中的 pandas 处理上传的 s(n=40k)。我逐行完成了这个工作,但这需要 15 到 20 分钟。这比我希望我的用户等待的时间要长,所以我正在寻找更有效的解决方案。

consultations我尝试了 pandas to_sql,但在调用to_sql函数之前,我无法弄清楚如何将两个外键关系作为列添加到我的数据框中。有没有办法将 Patient 和 Praktijk 外键添加为数据框中的列consultations

更具体地说,当逐行插入时,我使用类型 Patient的对象或Praktijk在数据库中创建新的咨询时。但是,在数据框中,我不能使用这些类型,因此不知道如何正确添加外键。是否可能有一个类型的值objectint(患者的 id?)可以替代 Patient 类型的值,从而设置外键?

Consultation型号:

class Consultation(models.Model):
    # the foreign keys
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE, null=True, blank=True)
    praktijk = models.ForeignKey(Praktijk, on_delete=models.CASCADE, default='')

    # other fields which do not give trouble with to_sql
    patient_nr = models.IntegerField(blank=True, null=True)
    # etc

to_sql来电:

consultations.to_sql(Consult._meta.db_table, engine, if_exists='append', index=False, chunksize=10000)

如果以上是不可能的,是否有其他更有效的解决方案的提示?

4

2 回答 2

2

我有同样的问题,这就是我解决它的方法。我的回答不是那么直截了当,但我相信它会有所帮助。

检查您的 django 项目以确保两件事:

  1. 目标表名
  2. 表列名称

就我而言,我class Meta在定义 django 模型时使用显式名称(django 有一种自动命名表的方法)。我将使用django 教程项目来说明。

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    class Meta:
        db_table = "poll_questions"

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    class Meta:
        db_table = "question_choices"

注意:Django 使用Question 对象的pk引用数据库中的 Question 外键。

假设我有一个 Question pk 1 和一个我希望用来更新 Question 选择的数据框df 。如果使用 pandas 批量插入数据库,我的 df 必须如下所示!

import pandas as pd  

df = pd.DataFrame(
    {
        "question": [1, 1, 1, 1, 1],
        "choice_text": [
            "First Question",
            "Second Question",
            "Third Question",
            "Fourth Question",
            "Fifth Question"
        ],
        "votes":[5,3,10,1,13]
    }
)

我希望我可以将 df 写成表格。太糟糕了,SO不支持表格的通常降价

尽管如此,我们的 df 下一步是创建用于插入记录的数据库连接。

from django.conf import settings
from sqlalchemy import create_engine

# load database settings from django

user = settings.DATABASES['default']['USER']
passwd = settings.DATABASES['default']['PASSWORD']
dbname = settings.DATABASES['default']['NAME']

# create database connection string
conn = 'postgresql://{user}:{passwd}@localhost:5432/{dbname}'.format(
    user=user,
    passwd=passwd,
    dbname=dbname
)

# actual database connection object.
conn = create_engine(conn, echo=False)

# write df into db
df.to_sql("question_choices", con=conn, if_exists="append", index=False, chunksize=500, method="multi")

瞧!
我们完了!

注意:
django 支持批量创建,但是,这不是您所要求的。

于 2020-09-14T14:28:21.703 回答
0

我使用 SQLalchemy 遇到了类似的问题,但我找到了一个简单的解决方法。

我所做的是使用 SQLalchemy 以我想要的方式定义数据库模式(使用我需要的所有数据类型和外键),然后创建一个空表,然后我只是将if_exists参数更改为append.

这会将所有数据附加到一个空数据库中。

于 2022-01-16T06:50:04.717 回答