2016-06-07 29 views
4

我已被存储在如以下所示的熊猫数据帧股票价格数据(实际上它是在一个面板,但我它转换为一个数据帧)保存大熊猫数据帧到一个Django模型

 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是我的数据框:

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

有没有更好的方法来保存?

我看了看django-pandas,但看起来好像只是从数据库中读取。

回答

10

这将是最有效的使用to_sql()适当connection参数的engine,并运行此您Django内部应用程序,而不是通过DataFrame迭代,并在节省时间的一个model例如:

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) 
+0

有没有办法让数据库生成的自动ID返回到'DataFrame'? (我的Excel数据需要存储在通过外键链接的多个Django模型中。) – Chris

+1

您可以随时使用[read_sql](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_sql.html )使用所有自动生成的列获取完整的df。如果这就是你所指的,django自己就会使用数据库生成的'id'。 – Stefan

+0

谢谢@Stefan,在我的情况下,确定我最新的行子集将是一个昂贵的操作,并可能出现错误。这是说替代[似乎](http://stackoverflow.com/questions/26770489/how-to-get-autoincrement-values-for-a-column-after-uploading-a-pandas-dataframe)被锁定表和手动设置ID,或写[通过CSV](http://stackoverflow.com/questions/31997859/bulk-insert-a-pandas-dataframe-using-sqlalchemy),所以也很可能打击性能或丢失ID,也许这只是批量插入的一个基本限制。我会做更多的研究并报告回来。 – Chris

-1

如果你不想直接惹SQL,你可以用这样的东西:

entries = df.to_dict('records') 
HistoricalPrices.objects.bulk_create(entries) 

我没有比较p性能,但我认为这更清洁。

+0

这将不起作用,因为您不能使用'bulk_create'与一系列的字典,只能使用'HistoricalPrices'对象列表。 – shabda