當我們使用Django建立了一個網站的框架後,一般而言,要存取此網站的資料庫基本上是要在Django框架的啟用狀態時進行存取,也就是你的網站需要是在執行中的狀態,我們以瀏覽器向伺服器存取在網站資料夾下的Python程式時,該程式才能夠以Django的ORM方式正確地存取它的附屬資料表。但有時候我們在進行網站資料維護時,尤其是一些比較耗時的資料處理程式時,其實是需要編寫另外獨立的程式讓管理者在伺服器上(或開發環境中)執行的,本文簡單地記錄了獨立程式存取Django資料庫的方法。
在開始之前要留意的是,Django框架在程式內是以ORM的方式而不是SQL程式存取資料表,它的資料表是在models.py中以class類別的方式所定義的,實際資料表的格式以及資料型態,是透過python manage.py makemigrations以及python manage.py migrate指令進行遷移轉換的,所以,如果你想要以獨立的程式利用SQL指令去直接存取Django網站的資料,是非常高風險的行為。因此,正確的方法是,在你的程式中導入Django資料庫的設定環境,仍然以ORM的方式存取它的資料表。
所以,重點是,只要在你的獨立Python程式(直接在Shell命令提示字元環境中執行,而非透過網頁伺服器委派)中準備好和你的Django網站一樣的環境,就可以順利地操作資料庫了。那麼,如何準備這樣的環境呢?
如果你只是要執行簡單的操作,沒有幾行指令的話,在命令列中輸入以下的指令,是最便利的方法:
python manage.py shell
沒錯,就是在Django網站的目錄下執行上面這個簡單的指令,它就會幫我們匯入Django網站的環境,讓我們直接使用,畫面如下:
在上述的交談式介面中,可以使用所有在Django程式中的ORM指令,當然還包括了新增、編輯、及刪除功能。
那麼,如果需要編寫更複雜的程式呢?沒問題,只要在程式的前面加上原本你的網站中在wsgi.py中的設定引入指令,再加上django.setup()就可以了,範例程式如下:
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tangwww.settings')
django.setup()
from mysite.models import Author
authors = Author.objects.all()
print(authors[:10])
在上面例子的第3行中,假設我們的settings.py是放在tangwww資料夾之下的話,那麼就可以利用透過這行引入所有網站中的設定資料,再利用第4行的django.setup()完成設定作業。接下來,就如你所看到的,在程式中也就可以輕易地利用ORM的方式,存取Author這張資料表了。執行的過程如下(假設上述的程式儲存為fixauthor.py):
以下就以一個例子來說明如何把從政府公開資訊網站中取得的資料,利用一個程式儲存到資料庫中。
假設我們想要建立一個流浪動物認養的查詢網站,首先到政府的公開資訊網站中找到以下這個連結:
https://data.gov.tw/dataset/53915
在此連結中可以下載到「臺南待認領養流浪動物資料」,它是以JSON的格式提供下載,點擊該資料之後可以看到以下的內容(只摘錄第1項資料):
[
{
"animal_id": 247178,
"animal_subid": "S110319-02",
"animal_area_pkid": 16,
"animal_shelter_pkid": 74,
"animal_place": "臺南市動物之家善化站",
"animal_kind": "狗",
"animal_sex": "F",
"animal_bodytype": "MEDIUM",
"animal_colour": "黑色",
"animal_age": "",
"animal_sterilization": "F",
"animal_bacterin": "F",
"animal_foundplace": "善化區菜市場",
"animal_title": "",
"animal_status": "OPEN",
"animal_remark": "本站動物皆採現場互動面談後評估能否認養 不接受系統上的預約",
"animal_caption": "",
"animal_opendate": "2022-03-26",
"animal_closeddate": "2999-12-31",
"animal_update": "2022/03/19",
"animal_createtime": "2022/03/19",
"shelter_name": "臺南市動物之家善化站",
"album_file": "",
"album_update": "",
"cDate": "2022/03/19",
"shelter_address": "臺南市善化區昌隆里東勢寮1~19號",
"shelter_tel": "06-5832399",
"animal_Variety": "混種狗"
},
...(省略)
]
從第一個符號我們可以看出它是一個串列的格式,裡面每一個都是字典型態,我們可以從字典的KEY中找出幾個我們感興趣的欄位建立網站的資料表,其中包括animal_id、animal_place、animal_kind、animal_sex、animal_status、animal_remark、animal_update、album_file等等,首先要把這些欄位新建到資料表中,也就是models.py,如下所示:
class Animal(models.Model):
aid = models.PositiveIntegerField()
place = models.CharField(max_length=100)
kind = models.CharField(max_length=20)
sex = models.BooleanField(default=False)
status = models.CharField(max_length=20, default="N/A")
remark = models.CharField(max_length=200)
update = models.DateField()
album = models.CharField(max_length=400)
def __str__(self):
return "{}({})".format(self.place, self.kind)
然後在admin.py中加入可以管理介面,如下所示:
@admin.register(Animal)
class AnimalAdmin(admin.ModelAdmin):
list_display = ('aid', 'place', 'kind', 'sex', 'status', 'remark', 'update')
之後再編寫一個dataimport.py的程式執行之後就可以把所有的資料都順利匯入到Django網站的資料庫中了。由於此程式需要到政府公開資訊網站中下載資料,所以執行之後請在你的虛擬環境中安裝requests模組:
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nkustweb.settings')
django.setup()
from mysite.models import Animal
import requests, json
url = "https://data.coa.gov.tw/Service/OpenData/TransService.aspx?UnitId=QcbUEzN6E6DL&animal_area_pkid=16"
jsondata = requests.get(url).text
data = json.loads(jsondata)
for item in data:
try:
rec = Animal()
rec.aid = item['animal_id']
rec.place = item['animal_place']
rec.kind = item['animal_kind']
if item['animal_sex']=="M":
rec.sex = True
rec.status = item['animal_status']
rec.remark = item['animal_remark']
rec.update = item['animal_update'].replace("/", "-")
rec.album = item['album_file']
rec.save()
except Exception as e:
print(e)
pass
print("Done")
在Django網站的主目錄下執行這個程式,之後再進入網站後台就可以看到我們的匯入成果: