Как написать фрейм данных Pandas в модель Django
Я использую pandas в python, и я обычно пишу фрейм данных в свою таблицу БД, как показано ниже. Теперь я мигрирую в 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)
2 ответов
используйте свой собственный код панды вдоль боковой модели Django, которая сопоставлена с той же SQL table
Я не знаю о какой-либо явной поддержке написания фрейма данных pandas для модели Django. Однако в приложении Django вы все равно можете использовать свой собственный код для чтения или записи в базу данных, в дополнение к использованию ORM (например, через вашу модель Django)
и учитывая, что у вас, скорее всего, есть данные в базе данных, ранее написанной pandas' to_sql
, вы можете продолжать использовать ту же база данных и тот же код панды и просто создать Django модель, которая может получить доступ к этой таблице
например, если ваш код панды писал в таблицу 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 = ...
теперь вы можете использовать эту модель из Django одновременно с существующим кодом панды (возможно, в одном приложении Django)
настройки базы данных Django
чтобы получить те же учетные данные БД в функциях 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
уже делает это за нас. И чтение запросов Django в фрейм данных pandas просто неэффективно, когда панды могут это сделать для нас тоже быстрее.
# Doing it like this is slow
for index, row in df.iterrows():
model = MyModel()
model.field_1 = row['field_1']
model.save()
Я просто прохожу через то же самое упражнение в данный момент. Подход, который я принял, заключается в создании списка новых объектов из фрейма данных, а затем групповое создание них:
bulk_create (objs, batch_size=нет)
этот метод эффективно вставляет предоставленный список объектов в базу данных (обычно только 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)