У меня есть приложение Django 1.1, которое необходимо ежедневно импортировать данные из некоторых больших json-файлов. Чтобы дать представление, один из этих файлов имеет более 100 Мб и содержит 90 тыс. Записей, которые импортируются в базу данных Postgresql.Оптимизация производительности базы данных Postgresql в Django?
Проблема, с которой я столкнулся, заключается в том, что импортируемые данные занимают очень много времени, то есть в порядке времени. Я ожидал, что потребуется некоторое время, чтобы написать это количество записей в базу данных, но, конечно, не так долго, что заставляет меня думать, что я делаю что-то по своей сути неправильно. Я читал похожие вопросы о стеке, и предлагаемые решения предлагают использовать декодеры transaction.commit_manually
или transaction.commit_on_success
для совершения в пакетах вместо каждого .save()
, который я уже делаю.
Как я уже сказал, мне интересно, что я делаю что-то неправильно (например, партии для фиксации слишком велики?), Слишком много внешних ключей? ...), или я должен просто уйти от моделей Django для эту функцию и напрямую использовать DB API. Любые идеи или предложения?
Вот основные модели я имею дело с при импорте данных (я удалил некоторые из полей в исходном коде для простоты)
class Template(models.Model):
template_name = models.TextField(_("Name"), max_length=70)
sourcepackage = models.TextField(_("Source package"), max_length=70)
translation_domain = models.TextField(_("Domain"), max_length=70)
total = models.IntegerField(_("Total"))
enabled = models.BooleanField(_("Enabled"))
priority = models.IntegerField(_("Priority"))
release = models.ForeignKey(Release)
class Translation(models.Model):
release = models.ForeignKey(Release)
template = models.ForeignKey(Template)
language = models.ForeignKey(Language)
translated = models.IntegerField(_("Translated"))
А вот немного кода, кажется принять возрастов, чтобы закончить:
@transaction.commit_manually
def add_translations(translation_data, lp_translation):
releases = Release.objects.all()
# There are 5 releases
for release in releases:
# translation_data has about 90K entries
# this is the part that takes a long time
for lp_translation in translation_data:
try:
language = Language.objects.get(
code=lp_translation['language'])
except Language.DoesNotExist:
continue
translation = Translation(
template=Template.objects.get(
sourcepackage=lp_translation['sourcepackage'],
template_name=lp_translation['template_name'],
translation_domain=\
lp_translation['translation_domain'],
release=release),
translated=lp_translation['translated'],
language=language,
release=release,
)
translation.save()
# I realize I should commit every n entries
transaction.commit()
# I've also got another bit of code to fill in some data I'm
# not getting from the json files
# Add missing templates
languages = Language.objects.filter(visible=True)
languages_total = len(languages)
for language in languages:
templates = Template.objects.filter(release=release)
for template in templates:
try:
translation = Translation.objects.get(
template=template,
language=language,
release=release)
except Translation.DoesNotExist:
translation = Translation(template=template,
language=language,
release=release,
translated=0,
untranslated=0)
translation.save()
transaction.commit()
Посмотрите на этот недавний ответ, который может иметь полезные полезные советы. http://stackoverflow.com/questions/9407442/optimise-postgresql-for-fast-testing/9407940#comment11914305_9407940 –
Вторая часть вопроса была разделена на [следующий вопрос здесь] (http: // stackoverflow. com/q/9447506/939860) –