如何将Pandas Dataframe写入Django模型

时间:2015-12-22 22:38:19

标签: python django postgresql pandas dataframe

我一直在python中使用pandas,我通常会将数据帧写入我的db表,如下所示。我现在正在迁移到Django,如何通过名为MyModel的模型将相同的数据帧写入表中?援助真的很感激。

# Original pandas code
    engine = create_engine('postgresql://myuser:mypassword@localhost:5432/mydb', echo=False)
    mydataframe.to_sql('mytable', engine,if_exists='append',index=True)

4 个答案:

答案 0 :(得分:12)

在映射到同一SQL表的Django模型旁边使用您自己的pandas代码

我不知道有任何明确的支持将pandas数据帧写入Django模型。但是,在Django应用程序中,除了使用ORM(例如通过Django模型)之外,您仍然可以使用自己的代码来读取或写入数据库

并且考虑到您最有可能在数据库中拥有以前由熊猫编写的数据' to_sql,您可以继续使用相同的数据库和相同的pandas代码,只需创建Django model that can access that table

e.g。如果您的pandas代码写入SQL表mytable,只需创建一个这样的模型:

class MyModel(Model):
    class Meta:
        db_table = 'mytable' # This tells Django where the SQL table is
        managed = False # Use this if table already exists
                        # and doesn't need to be managed by Django

    field_1 = ...
    field_2 = ...

现在你可以在现有的pandas代码中同时使用Django的这个模型(可能在一个Django应用程序中)

Django数据库设置

要获得相同的DB凭据到pandas SQL函数,只需读取Django设置中的字段,例如:

from django.conf import settings

user = settings.DATABASES['default']['USER']
password = settings.DATABASES['default']['PASSWORD']
database_name = settings.DATABASES['default']['NAME']
# host = settings.DATABASES['default']['HOST']
# port = settings.DATABASES['default']['PORT']

database_url = 'postgresql://{user}:{password}@localhost:5432/{database_name}'.format(
    user=user,
    password=password,
    database_name=database_name,
)

engine = create_engine(database_url, echo=False)

不推荐替代方案,因为效率低

除了逐行读取数据帧然后创建模型实例并保存它之外,我真的没有办法看到这种方法,这非常慢。你可能会逃避一些批量插入操作,但是为什么因为熊猫而烦恼呢? to_sql已经为我们做了。将pangas查询集读入pandas数据帧只是效率低下,当大熊猫也可以更快地为我们做这件事。

# Doing it like this is slow
for index, row in df.iterrows():
     model = MyModel()
     model.field_1 = row['field_1']
     model.save()

答案 1 :(得分:8)

我现在正在进行同样的练习。我采用的方法是从DataFrame创建一个新对象列表,然后bulk create创建它们:

  

bulk_create(objs,batch_size = None)

     

此方法以有效的方式将提供的对象列表插入到数据库中(通常只有1个查询,无论有多少个对象)

示例可能如下所示:

# Not able to iterate directly over the DataFrame
df_records = df.to_dict('records')

model_instances = [MyModel(
    field_1=record['field_1'],
    field_2=record['field_2'],
) for record in df_records]

MyModel.objects.bulk_create(model_instances)

答案 2 :(得分:0)

您现在可以按以下方式使用此midleware

library(kableExtra)

head(iris) %>% 
knitr::kable('html') %>%
kableExtra::kable_styling(full_width = TRUE, bootstrap_options = "basic")

答案 3 :(得分:0)

我的解决方案使用pickle和可选的zlib进行压缩

+