2013-07-29 2 views
1

Я хочу экспортировать мою базу данных в формате CSV. До сих пор «мой» код работает только для одной таблицы ...Экспорт всех моделей в файл csv

Вот мои модели:

class ActsIdsModel(models.Model): 
    year = models.IntegerField(max_length=4, blank=False, null=False) 
    ...lots of other fields... 

class NationRespModel(models.Model): 
    nationResp=models.CharField(max_length=2, unique=True) 

class EUGroupRespModel(models.Model): 
    euGroupResp=models.CharField(max_length=50, unique=True) 

class RespProposModel(models.Model): 
    respPropos=models.CharField(max_length=50, unique=True) 
    nationResp = models.ForeignKey('NationRespModel', blank=True, null=True, default=None) 
    euGroupResp = models.ForeignKey('EUGroupRespModel', blank=True, null=True, default=None) 

class GvtCompoModel(models.Model): 
    gvtCompo= models.CharField(max_length=1000, blank=False, null=False) 

class ActsInfoModel(models.Model): 
    #id of the act 
    actId = models.OneToOneField(ActsIdsModel, primary_key=True) 
    respProposId1=models.ForeignKey('RespProposModel', related_name='respProposId1', blank=True, null=True, default=None) 
    respProposId2=models.ForeignKey('RespProposModel', related_name='respProposId2', blank=True, null=True, default=None) 
    respProposId3=models.ForeignKey('RespProposModel', related_name='respProposId3', blank=True, null=True, default=None) 
    gvtCompo= models.ManyToManyField(GvtCompoModel) 
    ...lots of other fields... 

Я использую следующий код, чтобы экспортировать все данные из одной модели:

import csv 
from django.db.models.loading import get_model 

    def dump(qs, outfile_path): 
     model = qs.model 
     writer = csv.writer(open(outfile_path, 'w')) 

     headers = [] 
     for field in model._meta.fields: 
      headers.append(field.name) 
     writer.writerow(headers) 

     for obj in qs: 
      row = [] 
      for field in headers: 
       val = getattr(obj, field) 
       if callable(val): 
        val = val() 
       if type(val) == unicode: 
        val = val.encode("utf-8") 
       row.append(val) 
      writer.writerow(row) 

(источник: http://palewi.re/posts/2009/03/03/django-recipe-dump-your-queryset-out-as-a-csv-file/)

Вот как я получаю все мои модели (основная модель + модели связаны с главной):

db_queryset=ActsInfoModel.objects.select_related().all().prefetch_related('gvtCompo') 

Мой вопрос: как я могу связать этот запрос с функцией дампа? До сих пор я получаю данные только ActsInfoModel ...

Должен ли я использовать этот код, используемый для отображения и проверьте все данные:

for act in db_queryset.iterator(): 
    #ActsIdsModel 
    for field in act.actId.__class__._meta.fields: 
     print field.name, getattr(act.actId, field.name) 
    #ActsInformationModel 
    for field in act.__class__._meta.fields: 
     print field.name, getattr(act, field.name) 
    #RespProposModel (3 respPropos) 
    for index in xrange(1,4): 
     index=str(index) 
     try: 
      print getattr(act, "respProposId"+index).respPropos 
      print getattr(act, "respProposId"+index).nationResp.nationResp 
      print getattr(act, "respProposId"+index).euGroupResp.euGroupResp 
     except Exception, e: 
      print "exception", e 
    #NPModel (gvtCompo) 
    for gvtCompo in act.gvtCompo.all(): 
     print "gvtCompo", gvtCompo.gvtCompo 

ответ

1
**Export to CSV using the Django ORM** 

Django приложения, как правило, довольно данных тяжелый. Одной из общих задач является экспорт наборов данных в csv (значения, разделенные запятыми), простой текстовый файл, который может быть загружен в электронную таблицу и далее обрабатываться. Первое, что нужно сделать, это убедиться, что вы знаете о библиотеке csv Python.

Если вы экспортируете вы все данные по одной модели, здесь быстрый способ сделать это и сохранить свой код понятнее с помощью values_list и Django ORM стенографии запроса. Начните с определения вашего экспорта как структуры данных.

export_info = [ 
     ("Role", "role__name"), 
     ("Department", "department"), 
     ("Last Name", "person__last_name"), 
     ("First Name", "person__first_name"), 
    ] 

Первый элемент в кортеже - это заголовок строки, а второй элемент - путь ORM к требуемому значению. Он будет передан в values_list. Один из уловок: если у вас есть отношения, и вы не указываете поле в отношении, которое вас интересует, вы просто получите идентификатор объекта. Метод unicode модели не вызывается. Для лучшей идеи здесь будут выглядеть модели в этом примере.

class Position(models.Model): 
    role = models.ForeignKey("Role") 
    department = models.CharField(max_length=256) 
    person = models.ForeignKey("Person") 

class Role(models.Model): 
    name = models.CharField(max_length=256) 

class Person(models.Model): 
    first_name = models.CharField(max_length=256) 
    last_name = models.CharField(max_length=256) 
The core logic looks like this. 

global export_info 
positions = Position.objects.all().order_by("role__name", 
              "person__last_name") 
# The inverse of zip is zip 
headers, fields = zip(*export_info)  
rows = [headers] 
for position in positions: 
    qs = Position.objects.filter(pk=position.id)  
    # convert values like datetimes into unicode objects 
    rows.append([unicode(v) for v in qs.values_list(*fields)[0]]) 

Последняя линия, где происходит волшебство. Я предлагаю пройти через это в вашем интерпретаторе, если вы смущены тем, что он делает. Когда этот код будет выполнен, у вас будет список строк, которые являются вашим CSV-файлом. Осталось только записать результат в прокси-файл и вернуть его в ответ.

f = StringIO.StringIO() 
writer = UnicodeWriter(f) 
for row in rows: 
    writer.writerow(row) 
response = HttpResponse(f.getvalue(), mimetype="text/csv") 
response['Content-Disposition'] = 'attachment; filename=export.csv' 
return response 

Чтобы заставить StringIO «импортировать cStringIO как StringIO». UnicodeWriter для csv - это немного пользовательский код, вдохновленный этим разделом документов Python. Вы можете использовать обычный скрипт библиотеки csv, если все ваши данные являются ASCII и другим прокси-файлом файла, если хотите.

source

+0

Могу ли я использовать это для экспорта всех моделей, связанных с основным ActsInfoModel? Я читал «Если вы экспортируете все данные по одной модели» ... – rom