天天看點

django 批量導入資料

一、需求

我在資料庫中建了一張表,用來儲存ucloud雲上的project id 和project name

models.py代碼如下

1

2

3

4

5

6

7

8

9

10

<code>#coding:utf-8</code>

<code>from</code> <code>django.db </code><code>import</code> <code>models</code>

<code>class</code> <code>Project(models.Model):</code>

<code>    </code><code>name </code><code>=</code> <code>models.CharField(u</code><code>'項目名稱'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>id</code> <code>=</code> <code>models.CharField(u</code><code>'項目ID'</code><code>,max_length</code><code>=</code><code>32</code><code>,unique</code><code>=</code><code>True</code><code>,primary_key</code><code>=</code><code>True</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>create_date </code><code>=</code> <code>models.DateTimeField(u</code><code>'建立時間'</code><code>, auto_now_add</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>update_date </code><code>=</code> <code>models.DateTimeField(u</code><code>'更新時間'</code><code>, auto_now</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>def</code> <code>__unicode__(</code><code>self</code><code>):</code>

<code>        </code><code>return</code> <code>self</code><code>.name</code>

admin.py代碼如下

<code>from</code> <code>django.contrib </code><code>import</code> <code>admin</code>

<code>from</code> <code>ucloud.models </code><code>import</code> <code>*</code>

<code>class</code> <code>ProjectAdmin(admin.ModelAdmin):</code>

<code>    </code><code>list_display </code><code>=</code> <code>[</code><code>'name'</code><code>,</code><code>'id'</code><code>]</code>

<code>admin.site.register(Project,ProjectAdmin)</code>

<a href="https://s3.51cto.com/wyfs02/M02/8E/51/wKioL1i9NH_Dw8mwAABy5EJOxGo519.png" target="_blank"></a>

二、批量導入腳本

現在,我準備了一個腳本,通過UcloudAPI擷取到了線上所有的項目的項目ID和項目名稱

11

12

13

14

15

16

17

<code>#!/usr/bin/env python</code>

<code>#-*-coding:utf8-*-</code>

<code>from</code> <code>Ucloud_API.config </code><code>import</code> <code>*</code>

<code>from</code> <code>Ucloud_API.sdk </code><code>import</code> <code>UcloudApiClient</code>

<code>from</code> <code>models </code><code>import</code> <code>*</code>

<code>def</code> <code>get_project_info():</code>

<code>    </code><code>ApiClient </code><code>=</code> <code>UcloudApiClient(base_url, public_key, private_key)</code>

<code>    </code><code>Parameters </code><code>=</code> <code>{</code>

<code>        </code><code>"Action"</code><code>: </code><code>"GetProjectList"</code>

<code>    </code><code>}</code>

<code>    </code><code>response </code><code>=</code> <code>ApiClient.get(</code><code>"/"</code><code>, Parameters)</code>

<code>    </code><code>ids </code><code>=</code> <code>[</code>

<code>        </code><code>{</code><code>'ProjectId'</code><code>: _[</code><code>'ProjectId'</code><code>], </code><code>'ProjectName'</code><code>: _[</code><code>'ProjectName'</code><code>]}</code>

<code>        </code><code>for</code> <code>_ </code><code>in</code> <code>response[</code><code>'ProjectSet'</code><code>]</code>

<code>        </code><code>]</code>

<code>    </code><code>return</code> <code>ids</code>

<code>##腳本執行結果如下</code>

<code>[{</code><code>'ProjectId'</code><code>: u</code><code>'org-81'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'\u4e0a\u6d77\u522b\u6837\u7ea2\u4fe1\u606f\u6280\u672f\u6709\u9650\u516c\u53f8'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-ja1wvv'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'\u5907\u6848\u4e13\u7528'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-wrg10n'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'gitlab'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-pni2a2'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'PublicTest'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-kbxrx4'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'SPMS'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-aws3dj'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'\u5b89\u5168\u6d4b\u8bd5'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-vzfixt'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'OTA'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-et55qg'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'99\u6570\u636e\u540c\u6b65\u4e2d\u8f6c\uff0c\u672c\u9879\u76ee\u4e0e99\u5185\u7f51\u6253\u901a\uff0c\u4e0d\u5141\u8bb8\u6dfb\u52a0\u4efb\u4f55\u673a\u5668'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-ghan2t'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'Ops'</code><code>}, {</code><code>'ProjectId'</code><code>: u</code><code>'org-qf4d2n'</code><code>, </code><code>'ProjectName'</code><code>: u</code><code>'iPms'</code><code>}]</code>

ProjectId對象表中的id字段,ProjectName對應表中的name字段。

下面是批量導入資料的代碼:

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

<code>##通過API擷取資料</code>

<code>##批量導入資料</code>

<code>def</code> <code>update_project_info():</code>

<code>    </code><code>info </code><code>=</code> <code>get_project_info()</code>

<code>    </code><code>pids </code><code>=</code> <code>[]</code>

<code>    </code><code>for</code> <code>_ </code><code>in</code> <code>info:</code>

<code>        </code><code>projectid </code><code>=</code> <code>_[</code><code>'ProjectId'</code><code>]</code>

<code>        </code><code>pids.append(projectid)</code>

<code>        </code><code>project </code><code>=</code> <code>None</code>

<code>        </code><code>try</code><code>:</code>

<code>            </code><code>project </code><code>=</code> <code>Project.objects.get(pk</code><code>=</code><code>projectid)</code>

<code>        </code><code>except</code> <code>Project.DoesNotExist:</code>

<code>            </code><code>project </code><code>=</code> <code>Project(pk</code><code>=</code><code>projectid)</code>

<code>        </code><code>project.name </code><code>=</code> <code>_[</code><code>'ProjectName'</code><code>]</code>

<code>        </code><code>project.save()</code>

<code>    </code><code># 删除本地有但是ucloud上沒有的項目</code>

<code>    </code><code>projectids </code><code>=</code> <code>[_[</code><code>'pk'</code><code>] </code><code>for</code> <code>_ </code><code>in</code> <code>Project.objects.</code><code>all</code><code>().values(</code><code>'pk'</code><code>)]</code>

<code>    </code><code>diff_ids </code><code>=</code> <code>list</code><code>(</code><code>set</code><code>(projectids).difference(</code><code>set</code><code>(pids)))</code>

<code>    </code><code>Project.objects.</code><code>filter</code><code>(pk__in</code><code>=</code><code>diff_ids).delete()</code>

這裡導入資料的思路如下:

<code>try</code><code>:</code>

<code>    </code><code>project </code><code>=</code> <code>Project.objects.get(pk</code><code>=</code><code>projectid)</code>

<code>except</code> <code>Project.DoesNotExist:</code>

<code>    </code><code>project </code><code>=</code> <code>Project(pk</code><code>=</code><code>projectid)</code>

先通過get方法擷取對象,如果對象bu'存在,則用下面的方法建立該對象

<code>project </code><code>=</code> <code>Project(pk</code><code>=</code><code>projectid)</code>

如果對象存在,通過下面的方法更新ProjectName

<code>project.name </code><code>=</code> <code>_[</code><code>'ProjectName'</code><code>]</code>

<code>project.save()</code>

另外還有一個需要注意的地方是,資料庫中的資料要更新。

例如:線上之前有一個項目aaa,但是後來被删除了,那麼則需要從資料庫中删除該對象。

使用以下方法;

<code>projectids </code><code>=</code> <code>[_[</code><code>'pk'</code><code>] </code><code>for</code> <code>_ </code><code>in</code> <code>Project.objects.</code><code>all</code><code>().values(</code><code>'pk'</code><code>)]</code>

<code>diff_ids </code><code>=</code> <code>list</code><code>(</code><code>set</code><code>(projectids).difference(</code><code>set</code><code>(pids)))</code>

<code>Project.objects.</code><code>filter</code><code>(pk__in</code><code>=</code><code>diff_ids).delete()</code>

将資料庫中的對象清單轉換成集合,将線上擷取到的對象清單也轉換成集合,然後通過

<code>set1.difference(set2)</code>

的方法來擷取在set1中存在,但在set2中不存在的對象,然後用下面的方法删除

批量導入資料還可以使用下面的方法執行

<code>    </code><code>pids </code><code>=</code> <code>[_[</code><code>'ProjectId'</code><code>] </code><code>for</code> <code>_ </code><code>in</code> <code>info]</code>

<code>    </code><code>for</code> <code>i </code><code>in</code> <code>info:</code>

<code>        </code><code>Project.objects.get_or_create(</code><code>id</code><code>=</code><code>i[</code><code>'ProjectId'</code><code>],name</code><code>=</code><code>i[</code><code>'ProjectName'</code><code>])</code>

<code>    </code><code>#擷取資料庫中存在,但線上不存在的projectid</code>

<code>    </code><code>#删除資料庫中多餘的資料</code>

<code>Project.objects.get_or_create(</code><code>id</code><code>=</code><code>i[</code><code>'ProjectId'</code><code>],name</code><code>=</code><code>i[</code><code>'ProjectName'</code><code>])</code>

 get_or_create() 有就擷取過來,沒有就建立,用它可以避免重複,但是速度可以會慢些,因為要先嘗試擷取,看看有沒有

三、如何執行腳本

我們可以将導入資料的方法通過問url的方式,來執行

<code>from</code> <code>django.shortcuts </code><code>import</code> <code>render</code>

<code>from</code> <code>django.http </code><code>import</code> <code>HttpResponse,JsonResponse</code>

<code>from</code> <code>sdkucloud </code><code>import</code> <code>*</code>

<code># Create your views here.</code>

<code>def</code> <code>index(request):</code>

<code>    </code><code>return</code> <code>HttpResponse(</code><code>'index'</code><code>)</code>

<code>def</code> <code>pull_project(request):</code>

<code>    </code><code>update_project_info()</code>

<code>    </code><code>return</code> <code>HttpResponse(</code><code>'OK!'</code><code>)</code>

編輯$APPName/urls.py

<code>from</code> <code>django.conf.urls </code><code>import</code> <code>include, url</code>

<code>from</code> <code>ucloud.views </code><code>import</code> <code>*</code>

<code>urlpatterns </code><code>=</code> <code>[</code>

<code>    </code><code>url(r</code><code>'^$'</code><code>,  index),</code>

<code>    </code><code>url(r</code><code>'^pull_project/$'</code><code>, pull_project)</code>

<code>]</code>

<code></code>

本文轉自 曾哥最愛 51CTO部落格,原文連結:http://blog.51cto.com/zengestudy/1903718,如需轉載請自行聯系原作者