2013-07-29 19 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(逗號分隔值),這是一個純文本文件,可以在電子表格中加載並進一步操作。首先要做的是確保你瞭解Python的csv庫。

如果您要導出所有關於一個模型的數據,請使用 這種快捷方式,並使用values_list和Django ORM查詢縮寫來保持代碼清潔。首先將導出定義爲數據結構。

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

元組中的第一項是行標題,第二項是您想要的值的ORM路徑。它將被傳遞給values_list。要注意的一個怪癖是如果你有一種關係,並且你沒有指定關係中的字段,那麼你只會得到該對象的id。該模型的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執行「import cStringIO as StringIO」。用於csv的UnicodeWriter是由Python文檔的這一部分啓發的一些自定義代碼。 如果所有的數據都是ASCII和不同的文件代理對象,您可以使用普通的csv庫編寫器。

source

+0

我可以用這個導出鏈接到主一個ActsInfoModel的所有型號?我讀到「如果你正在出口所有關於一個模型的數據」...... – rom