flask + sqlite3 + android 構建RESTful API實現個人資訊查詢系統 (上(伺服器端))
阿新 • • 發佈:2019-02-11
手裡有一些資料,原來是xls格式的,需要查詢一些資訊的時候用ecxel很不方便,所以便想做一套查詢系統,最好是Andriod的,隨時隨地就可以查詢,說幹就幹。
一、伺服器端
1.1
以前沒有接觸過後端,只做過安卓和前端,在問了其他人和上網搜尋比較之後,有以下幾種方案:
1.webservice
2.Java
3.Python的flask
考慮到伺服器的配置比較低(1核、1G、Ubuntu 14.04)以及需求很簡單(移動端請求查詢,伺服器端處理並向資料庫查詢後,通過JSON返回到移動端),遂決定採用flask
至於資料庫,由於資料比較少,只有幾千條,所以採用了sqlite3。
最終服務端要求實現的效果是:提供一套API,移動端訪問提供的API地址,伺服器將資料通過JSON返回。
1.2 設計一個簡單的API
一般情況,一個編號唯一對應一個人,所以只需要請求編號就可以。但有些時候僅知道姓名,這時候需要提供通過姓名查詢的方法。 API如下:HTTP方法 | URI | 動作 |
GET | http://[hostname]/[id] | 返回資訊 |
GET | http://[hostname]/[name] | 返回資訊 |
1.3 初步瞭解flask
flask是一個知名的Python框架,可以快速的開發web應用,他的安裝和部署也十分快捷。 先安裝virtualenv虛擬環境,virtualenv是開發Python必備的,提供Python虛擬環境,可以理解為一個沙箱,防止不同專案之間互相沖突。 使用xshell連線到伺服器$ sudo apt-get install python-virtualenv安裝成功之後,建立一個相關環境
$ virtualenv flaskapp這裡virtualenv建立了一個資料夾,flaskapp/,並且設定了一個純淨的python拷貝,同時安裝了包管理器pip。 進入新建立的開發環境並激活:(注意第二行period與bin之間有一個空格)
$ cd flaskapp $ . bin/activate接下來就可以安全地安裝Flask了:
$ pip install Flask接下來,建立我們的第一個flask應用,看一下flask是否安裝成功
$ vi hello.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/', methods=['GET']) # '/' 這一部分表示訪問的URL
def home(): <span style="white-space:pre"> </span> # def xxx() 表示對應響應的操作
return "Hello,World"
if __name__ == '__main__':
app.run(debug=True)
儲存後,執行
$ python hello.py
訪問本地IP,埠5000.
看到如下頁面:
[這裡應該有張圖]
這樣,我們的flask就架設成功了。
在這裡可能會有一個小問題,在伺服器上架設flask,可能有的朋友會在本地機器上直接訪問伺服器IP,結果卻發現無法開啟。此時,只需要將最後一句程式碼改為
app.run(host='0.0.0.0')
這樣,就可以被任意IP訪問了。
1.4 安裝Sqlite3資料庫
依然連線伺服器,執行 $ sudo apt-get install sqlite sqlite3 接下來建立資料庫 $ sqlite3 test.db 對於sqlite3的操作,為了方便起見,我們使用WinSCP將其下載到本地,在本地對其進行操作 在這裡推薦一個Win下操作sqlite3資料庫的小工具 sqlitestudio 在使用過程中可能會報錯,不過不用理會就好。 在本地建表,匯入資料。1.4.2 將EXCEL表格轉入到資料庫中
上千條資料,雖然不多,但是將其手動輸入到資料庫中似乎是一個不可能完成的任務。幸好sqlitestudio提供了轉換功能。但是需要將xls檔案轉換成csv之後才可匯入,這裡又有一個問題: xls檔案轉換成csv檔案之後,對於長資料項,比如身份證號一類,會造成精度損失。即使將所有單元格設定成“文字”也無濟於事。 解決辦法:先建立一個空白的csv檔案,將所有單元格設定為“文字”格式,然後將原xls檔案資料貼上到新建的csv檔案中。 這樣就可以保留資料。 建表過程不再贅述。
1.5 編寫服務端程式碼
在flask中使用sqlite3,需要新增如下程式碼:def connect_db():
return sqlite3.connect('test.db')
@app.before_request
def before_request():
g.db = connect_db()
@app.teardown_request
def teardown_request(exception):
if hasattr(g, 'db'):
g.db.close()
之後利用遊標來查詢資料
程式碼如下:
cursor = sqlite3.connect('test.db').cursor()
cursor.execute(這裡嵌入sql語句)
result = cursor.fetchall()
cursor.close()
sqlite3.connect('test.db').close()
這樣,資料庫查詢的資料就儲存到了result中
result[0]代表查詢到的第一條記錄
result[0][0]代表查詢到的第一條記錄的第一個值
前面我們提到,在flask中
@app.route('/xxx', methods=['GET'])
def xxx() :
# 執行程式碼
表示對http://[hostname]/xxx 進行響應,並執行xxx()函式。為了實現我們設計的API,所以我們為其新增響應編號的程式碼,並和之前的查詢程式碼綜合起來,程式碼如下:
@app.route('/<int:user_id>', methods=['GET'])
def query(user_id):
cursor = sqlite3.connect('test.db').cursor()
# #query
sql = "select name,stu_id,sex,mz,cla_id,place,ro_id,do_id,date,school,address from myer where stu_id = "+ str(user_id) <span style="white-space:pre"> </span>#這裡通過字串的方式達到在sql語句中插入變數的目的。
cursor.execute(sql)
result = cursor.fetchall()
print "query has been ok"
print sql
cursor.close()
sqlite3.connect('test.db').close()
return jsonify(
{
'user_id': user_id,
'name': result[0][0],
'stu_id': result[0][1],
'sex': result[0][2],
'mz': result[0][3],
'cla_id': result[0][4],
'place': result[0][5],
'ro_id': result[0][6],
'do_id': result[0][7],
'date': result[0][8],
'address': result[0][9]
})
(通過flask的jsonify實現對資料的JSON化)
接下來實現用名字來查詢,方法大同小異,就不再贅述了。
值得注意的是,為了防止查詢中文引起的編碼錯誤,需要在hello.py的開頭加入如下程式碼:
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
同時,在查詢的sql語句中,中文的兩端需要加上雙引號
sql = "select name,stu_id,sex,mz,cla_id,place,ro_id,do_id,date,school,address from myer where name = "+"\""+user_name+"\""注意引號個數。
1.6 完整程式碼
到這裡,伺服器端就算是開發完成了。完整程式碼如下:import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
import sqlite3
from flask import g
from flask import Flask, jsonify
app = Flask(__name__)
def connect_db():
return sqlite3.connect('test.db')
@app.before_request
def before_request():
g.db = connect_db()
@app.teardown_request
def teardown_request(exception):
if hasattr(g, 'db'):
g.db.close()
@app.route('/<int:user_id>', methods=['GET'])
def query(user_id):
cursor = sqlite3.connect('test.db').cursor()
# #query
sql = "select name,stu_id,sex,mz,cla_id,place,ro_id,do_id,date,school,address from myer where stu_id = "+ str(user_id)
cursor.execute(sql)
result = cursor.fetchall()
print "query has been ok"
print sql
cursor.close()
sqlite3.connect('test.db').close()
return jsonify(
{
'user_id': user_id,
'name': result[0][0],
'stu_id': result[0][1],
'sex': result[0][2],
'mz': result[0][3],
'cla_id': result[0][4],
'place': result[0][5],
'ro_id': result[0][6],
'do_id': result[0][7],
'date': result[0][8],
'address': result[0][9]
})
@app.route('/<user_name>', methods=['GET'])
def query_a(user_name):
cursor = sqlite3.connect('test.db').cursor()
# #query
sql = "select name,stu_id,sex,mz,cla_id,place,ro_id,do_id,date,school,address from myer where name = "+ "\""+user_name+"\""
cursor.execute(sql)
result = cursor.fetchall()
print "query has been ok"
print sql
cursor.close()
sqlite3.connect('test.db').close()
return jsonify(
{
'name': result[0][0],
'stu_id': result[0][1],
'sex': result[0][2],
'mz': result[0][3],
'cla_id': result[0][4],
'place': result[0][5],
'ro_id': result[0][6],
'do_id': result[0][7],
'date': result[0][8],
'address': result[0][9]
})
@app.route('/', methods=['GET'])
def home():
return "11"
@app.route('/ok', methods=['GET'])
def ok():
return "Hello,World"
@app.errorhandler(404)
def page_not_found(e):
res = jsonify({'error': 'not found'})
res.status_code = 404
return res
if __name__ == '__main__':
app.run(host='0.0.0.0')