1

我想以 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
4

1 回答 1

2
**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,请执行“将 cStringIO 作为 StringIO 导入”。用于 csv 的 UnicodeWriter 是受 Python 文档这一部分启发的一些自定义代码。如果您的所有数据都是 ASCII 和不同的文件代理对象,如果您愿意,您可以使用普通的 csv 库编写器。

资源

于 2013-07-29T19:11:40.807 回答