2016-06-07 4 views
4

я данные о ценах акций, которые хранятся в DataFrame панд, как показано ниже (на самом деле это было в панели, но я преобразовал его в DataFrame)Сохранение панды DataFrame в 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 

I хотят сохранить это в модели Django, который выглядит следующим образом (совпадает с именами столбцов):

class HistoricalPrices(models.Model): 
    ticker = models.CharField(max_length=10) 
    date = models.DateField() 
    tsr = models.DecimalField() 
    close = models.DecimalField() 

лучшим, что я придумал до сих пор использую это, чтобы сохранить его, где ДФ мой DataFrame:

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

Есть ли способ получить идентификатор авто, сгенерированный базой данных, в «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) должна блокировать таблицу и вручную установить идентификатор или написать [через CSV] (http://stackoverflow.com/questions/31997859/bulk-insert-a-pandas-dataframe-using-sqlalchemy), что также может повлиять на производительность или потерять идентификаторы, и, возможно, это всего лишь фундаментальное ограничение объемных вставок. Я сделаю больше исследований и отчитаюсь. – Chris

-1

Если вы не хотите связываться с sql напрямую, вы можете использовать что-то вроде этого:

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

Я не сравнил p но я думаю, что это намного чище.

+0

Это не сработает, потому что вы не можете использовать 'bulk_create' со списком dicts, только со списком объектов HistoricalPrices. – shabda

Смежные вопросы