将Pandas DataFrame保存到Django模型

19

我有一些股票价格数据,存储在pandas的DataFrame中,如下所示(实际上它是在一个panel中,但我将其转换为DataFrame)

        date  ticker  close       tsr
0 2013-03-28  abc     22.81  1.000439
1 2013-03-28  def     94.21  1.006947
2 2013-03-28  ghi     95.84  1.014180
3 2013-03-28  jkl     31.80  1.000000
4 2013-03-28  mno     32.10  1.003125
...many more rows
我想将这个保存在一个 Django 模型中,该模型如下所示(与列名相匹配):
class HistoricalPrices(models.Model):
    ticker = models.CharField(max_length=10)
    date = models.DateField()
    tsr = models.DecimalField()
    close = models.DecimalField()

到目前为止我想到的最好方法是使用以下代码保存数据,其中 df 是我的 DataFrame:

entries = []
for e in df.T.to_dict().values():
    entries.append(HistoricalPrices(**e))
HistoricalPrices.objects.bulk_create(entries)

有更好的保存方式吗?

我已经查阅了django-pandas,但它似乎只能从数据库中读取。

2个回答

27

最高效的方法是使用适当的connection参数和engine来运行to_sql(),并在您的Django应用程序中运行它,而不是遍历DataFrame并逐个保存model实例:

from sqlalchemy import create_engine
from django.conf import settings

user = settings.DATABASES['default']['USER']
password = settings.DATABASES['default']['PASSWORD']
database_name = settings.DATABASES['default']['NAME']

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)
df.to_sql(HistoricalPrices, con=engine)

1
你始终可以使用 read_sql 获取完整的带有所有自动生成列的 df。如果你指的是 Django 自己生成的 id,那么它将仅使用数据库生成的 id - Stefan
1
两个问题 -- (1) 是否有一种方法可以从设置中加载database_url,而不是硬编码它? (2) 这是最矢量化的方法吗? - Vishal
对于那些在使用pandas to_sql函数与django模型时遇到困难的人,你可能需要指定数据库表名而不是模型名称,如下所示:df.to_sql(HistoricalPrices._meta.db_table, con=engine) - hasan najeeb
@petroslamb 请查看帖子中链接的pandas 文档 - Stefan
那是一个SQLAlchemy引擎。没有提到使用该依赖项,同时在那里使用两个ORM有点过度杀伤力了。但我猜这是Pandas唯一支持的ORM? - petroslamb
显示剩余8条评论

0
更简单的方法,你可以尝试这个:
json_list = json.loads(json.dumps(list(df.T.to_dict().values())))

for dic in json_list:
     HistoricalPrices.objects.get_or_create(**dic)

5
逐行插入永远不是一个好选择。代码行数越少并不重要。 - anishtain4
@anishtain4,你也可以使用bulk_create,但如果你想检查数据库中是否存在某一行,则不能使用bulk_create,你应该逐行插入。 - Amir.S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接