操作簡單的 GAE 後,開始來摸摸資料儲存的部分。對於 GAE DB 的部分,操作不難,跟 Django 很像,先定義一個 Data Model (資料庫的資料表),接著就可以操作了!此例僅簡單帶過,更豐富的操作方式請參考官網 GAE - 資料模型。
建立 NewsData 資料模型:
from google.appengine.ext import db
class NewsData(db.Model):
check = db.StringProperty()
url = db.StringProperty()
title = db.StringProperty()
date = db.DateProperty()
新增一筆資料:
import datetime
item = NewsData(chech='1',url='http://localhost',title='TestNews',date=datetime.datetime.now().date())
item.put()
查詢資料:
使用 Data Model 查詢:
q = NewsData.all()
results = q.fetch(3)
for p in results:
print '<a href="%s">%s</a>' % (p.url,p.title)
使用 GqlQuery 之 SQL 語法:
# 查詢 3 天內的新聞
q = db.GqlQuery("SELECT * FROM NewsData WHERE date > :1 ORDER BY date DESC", datetime.datetime.now().date() - datetime.timedelta(days=3) )
results = q.fetch(3)
for p in results:
print '<a href="%s">%s</a>' % (p.url,p.title)
上述都很淺顯易懂,接著能嘗試簡易的 MVC 架構,把 DB Modle 定義在 mydb.py 檔,由 myput.py 和 myquery.py 作為 CGI 來操作(MVC的 VC 偷懶合在一起 XD)。
目錄結構:
app.yaml
favicon.ico
index.yaml
main.py
mydb.py
myquery.py
myput.py
app.yaml:
application: engineapp
version: 1
runtime: python
api_version: 1
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: /query
script: myquery.py
- url: /put
script: myput.py
- url: .*
script: main.py
mydb.py:
from google.appengine.ext import db
class NewsData(db.Model):
check = db.StringProperty()
url = db.StringProperty()
title = db.StringProperty()
date = db.DateProperty(auto_now_add=True)
myput.py:
# -*- coding: utf-8 -*-
print 'Content-Type: text/html'
print ''
import mydb
import cgi, hashlib, datetime, urllib
from google.appengine.ext import db
request = cgi.FieldStorage()
newsDate = datetime.datetime.now().date()
newsTitle = 'defaultTitle' if request is None or 'title' not in request or request['title'].value == '' else cgi.escape(request['title'].value)
newsURL = 'http://localhost' if request is None or 'url' not in request or request['url'].value == '' else request['url'].value
newsCheck = hashlib.md5(str(newsTitle)+str(newsURL)).hexdigest()
if mydb.NewsData.all().filter('check =',newsCheck).get() is None:
item = mydb.NewsData(check=newsCheck,url=unicode(newsURL,'utf-8'),title=unicode(newsTitle,'utf-8'),date=newsDate)
item.put()
print 'Put'
else:
print 'No Operation'
myquery.py:
# -*- coding: utf-8 -*-
print 'Content-Type: text/html'
print ''
import mydb
import datetime
from google.appengine.ext import db
print """
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
"""
q = db.GqlQuery("SELECT * FROM NewsData WHERE date > :1 ORDER BY date DESC", datetime.datetime.now().date() - datetime.timedelta(days=3) )
results = q.fetch(50)
for p in results:
url = p.url
date = p.date
check = p.check
title = p.title
print '<a href="%s">[%s] %s(%s)</a><br />' % ( url.encode('utf-8'), date, title.encode('utf-8'), check.encode('utf-8') )
print """
</body>
</html>
"""
如此一來,透過瀏覽 http://localhost:port/put (或 http://localhost:port/put?title=123&url=www.google.com ) 新增資料,透過 http://localhost:port/query 顯示資料。除此之外,還可以透過 Google App Engine Launcher 的 SDK Console ,直接用瀏覽器去查看資料庫的東西,實在方便:
這邊容易碰到的問題是 DB 內資料的編碼問題,我在 myput.py 把 CGI 得到的東西用 unicode(data,'utf-8') 的存進資料庫,在 myquery.py 時,則是用 data.encode('utf-8') 處理印出的部分。
沒有留言:
張貼留言