我想用Django(3,000行和100列)导出数据库(15或20个表),但这需要很长时间。
我认为解决方案是使用prefetch_related
,但我想你的意见,因为它对我来说似乎非常复杂(这么多表...)。如果这是解决方案,你能展示一些不同型号的例子吗?
def get_validated_acts(excl_fields_act_ids, excl_fields_act):
qs=Act.objects.filter(validated=2)
#list of acts
acts=[]
for act in qs.iterator():
#list of fields for one act
fields=[]
act_ids=ActIds.objects.get(act=act, src="index")
#ActIds
for field in ActIds()._meta.fields:
if field.name not in excl_fields_act_ids:
fields.append(getattr(act_ids, field.name))
#Act
for field in Act()._meta.fields:
if field.name not in excl_fields_act:
#CodeSect and related
if "code_sect_" in field.name:
temp=getattr(act, field.name)
if temp!=None:
fields.append(temp.code_sect)
fields.append(temp.code_agenda.code_agenda)
else:
fields.extend([None, None])
#Rapporteurs (Person) and related (oeil) or Responsibles (Person) and related (prelex)
elif "rapp_" in field.name or "resp_" in field.name:
temp=getattr(act, field.name)
if temp!=None:
fields.append(temp.name)
country=temp.country
party=temp.party
fields.append(country.country_code)
fields.append(party.party)
if "resp_" in field.name:
#party_family
fields.append(PartyFamily.objects.get(party=party, country=country).party_family)
else:
if "resp_" in field.name:
temp=[None]*4
else:
temp=[None]*3
fields.extend(temp)
else:
#for all the other non fk fields, get its value
fields.append(getattr(act, field.name))
#Act many to many fields
for field in Act()._meta.many_to_many:
#GvtCompo
if "gvt_compo"==field.name:
gvt_compos_country=gvt_compos_party=gvt_compos_party_family=""
#for each country
for gvt_compo in getattr(act, field.name).all():
country=gvt_compo.country
#for each party, add a "row" for each variable (country, party, party family)
for party in gvt_compo.party.all():
gvt_compos_country+=country.country_code+"; "
gvt_compos_party+=party.party+"; "
gvt_compos_party_family+=PartyFamily.objects.get(country=country, party=party).party_family+"; "
#delete last "; "
fields.append(gvt_compos_country[:-2])
fields.append(gvt_compos_party[:-2])
fields.append(gvt_compos_party_family[:-2])
#adopt_cs_contre, adopt_cs_abs, adopt_pc_contre, adopt_pc_abs
else:
countries=""
for country in getattr(act, field.name).all():
countries+=country.country_code+"; "
fields.append(countries[:-2])
#Ministers' attendance fields
instances=MinAttend.objects.filter(act=act)
temp_fields={"country": "", "verbatim": "", "status": ""}
for instance in instances:
temp_fields["country"]+=instance.country.country_code+"; "
temp_fields["verbatim"]+=instance.verbatim.verbatim+"; "
temp_fields["status"]+=Status.objects.get(verbatim=instance.verbatim, country=instance.country).status+"; "
fields.append(temp_fields["country"][:-2])
fields.append(temp_fields["verbatim"][:-2])
fields.append(temp_fields["status"][:-2])
acts.append(fields)
return acts
如果有帮助,这里是主模型Act
的一些字段:
class Act(models.Model):
titre_en=models.CharField(max_length=1000, blank=True, null=True, default=None)
code_sect_1=models.ForeignKey(CodeSect, related_name='code_sect_1', blank=True, null=True, default=None)
code_sect_2=models.ForeignKey(CodeSect, related_name='code_sect_2', blank=True, null=True, default=None)
code_sect_3=models.ForeignKey(CodeSect, related_name='code_sect_3', blank=True, null=True, default=None)
code_sect_4=models.ForeignKey(CodeSect, related_name='code_sect_4', blank=True, null=True, default=None)
rep_en_1=models.CharField(max_length=200, blank=True, null=True, default=None)
rep_en_2=models.CharField(max_length=200, blank=True, null=True, default=None))
type_acte=models.CharField(max_length=100, blank=True, null=True, default=None)
com_amdt_tabled=models.IntegerField(max_length=3, blank=True, null=True, default=None)
votes_agst_1=models.IntegerField(max_length=3, blank=True, null=True, default=None)
rapp_1=models.ForeignKey(Person, related_name='rapp_1', blank=True, null=True, default=None)
rapp_2=models.ForeignKey(Person, related_name='rapp_2', blank=True, null=True, default=None)
rapp_3=models.ForeignKey(Person, related_name='rapp_3', blank=True, null=True, default=None)
rapp_4=models.ForeignKey(Person, related_name='rapp_4', blank=True, null=True, default=None)
adopt_propos_origine=models.DateField(max_length=10, blank=True, null=True, default=None)
com_proc=models.CharField(max_length=100, blank=True, null=True, default=None)
resp_1=models.ForeignKey(Person, related_name='resp_1', blank=True, null=True, default=None)
resp_2=models.ForeignKey(Person, related_name='resp_2', blank=True, null=True, default=None)
resp_3=models.ForeignKey(Person, related_name='resp_3', blank=True, null=True, default=None)
transm_council=models.DateField(max_length=10, blank=True, null=True, default=None)
adopt_cs_contre=models.ManyToManyField(Country, related_name='adopt_cs_contre')
adopt_cs_abs=models.ManyToManyField(Country, related_name='adopt_cs_abs')
adopt_pc_contre=models.ManyToManyField(Country, related_name='adopt_pc_contre')
adopt_pc_abs=models.ManyToManyField(Country, related_name='adopt_pc_abs')
gvt_compo=models.ManyToManyField(GvtCompo)
答案 0 :(得分:0)
此代码似乎更快(速度提高10%):
def get_validated_acts(excl_fields_act_ids, excl_fields_act):
tic=time.time()
#querysets
qs_act=Act.objects.defer("id", 'date_doc', "url_prelex", "validated", "validated_attendance").filter(validated=2).prefetch_related("gvt_compo", "adopt_cs_contre", "adopt_cs_abs", "adopt_pc_contre", "adopt_pc_abs").prefetch_related("gvt_compo__party")
qs_actids=ActIds.objects.defer("id", 'src', "url_exists", 'act').filter(src="index")
qs_cs=CodeSect.objects.all().prefetch_related("code_agenda", "config_cons")
qs_pers=Person.objects.all()
qs_party=Party.objects.all()
qs_pf=PartyFamily.objects.all()
qs_minattend=MinAttend.objects.all()
qs_verb=Verbatim.objects.all()
qs_status=Status.objects.all()
#fields names
names_actids=[field.name for field in ActIds()._meta.fields if field.name not in excl_fields_act_ids]
names_act=[field.name for field in Act()._meta.fields if field.name not in excl_fields_act]
names_act_m2m=[field.name for field in Act()._meta.many_to_many]
#list of acts
acts=[]
for act in qs_act:
#list of fields for one act
fields=[]
act_ids=qs_actids.get(act=act)
#ActIds
for field in names_actids:
fields.append(getattr(act_ids, field))
#Act
for field in names_act:
#CodeSect and related
if "code_sect_" in field:
cs_id=getattr(act, field+"_id")
if cs_id!=None:
cs=qs_cs.get(pk=cs_id)
fields.append(cs.code_sect)
fields.append(cs.code_agenda.code_agenda)
else:
fields.extend([None, None])
#Rapporteurs (Person) and related (oeil) or Responsibles (Person) and related (prelex)
elif "rapp_" in field or "resp_" in field:
pers_id=getattr(act, field+"_id")
if pers_id!=None:
pers=qs_pers.get(pk=pers_id)
party=qs_party.get(pk=pers.party_id)
fields.append(pers.name)
fields.append(pers.country_id)
fields.append(party.party)
if "resp_" in field:
#party_family
fields.append(qs_pf.get(party=party, country_id=pers.country_id).party_family)
else:
if "resp_" in field:
temp=[None]*4
else:
temp=[None]*3
fields.extend(temp)
else:
#for all the other non fk fields, get its value
fields.append(getattr(act, field))
#~
#Act many to many fields
for field in names_act_m2m:
#GvtCompo
if "gvt_compo"==field:
gvt_compos_country=gvt_compos_party=gvt_compos_party_family=""
#~ #for each country
for gvt_compo in act.gvt_compo.all():
#for each party, add a "row" for each variable (country, party, party family)
for party in gvt_compo.party.all():
gvt_compos_country+=gvt_compo.country_id+"; "
gvt_compos_party+=party.party+"; "
gvt_compos_party_family+=qs_pf.get(party=party, country_id=gvt_compo.country_id).party_family+"; "
#delete last "; "
fields.append(gvt_compos_country[:-2])
fields.append(gvt_compos_party[:-2])
fields.append(gvt_compos_party_family[:-2])
#~ #adopt_cs_contre, adopt_cs_abs, adopt_pc_contre, adopt_pc_abs
else:
countries=""
for country in getattr(act, field).all():
countries+=country.country_code+"; "
fields.append(countries[:-2])
#~
#Ministers' attendance fields
instances=qs_minattend.filter(act=act)
temp_fields={"country": "", "verbatim": "", "status": ""}
for instance in instances:
temp_fields["country"]+=instance.country_id+"; "
temp_fields["verbatim"]+=qs_verb.get(pk=instance.verbatim_id).verbatim+"; "
temp_fields["status"]+=qs_status.get(verbatim_id=instance.verbatim_id, country_id=instance.country_id).status+"; "
fields.append(temp_fields["country"][:-2])
fields.append(temp_fields["verbatim"][:-2])
fields.append(temp_fields["status"][:-2])
acts.append(fields)
tac=time.time()
print "time", tac-tic
return acts
我使用prefetch_related
并将所有对象存储在内存中。不确定这是个好主意......