操作簡單的 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 ,直接用瀏覽器去查看資料庫的東西,實在方便:

GAE11

這邊容易碰到的問題是 DB 內資料的編碼問題,我在 myput.py 把 CGI 得到的東西用 unicode(data,'utf-8') 的存進資料庫,在 myquery.py 時,則是用 data.encode('utf-8') 處理印出的部分。


, , , , , , , ,

changyy 發表在 痞客邦 PIXNET 留言(0) 人氣()