python學習日記-2016.7.28

1.使用PyMySQL連接mysql

在成功連接python內嵌的sqlite后,我想嘗試連接這個世界使用人數最多的數據庫-MySQL盯滚。于是我去MySQL官網查找官方提供的python驅動兽埃,只找到python3.4版本的侦鹏,而我自己使用的是python3.5.2铜跑,因此無法安裝湿右,百度后發(fā)現(xiàn)有個替代品,即PyMySQL,我在pip中成功得安裝了它并成功得鏈接到我本地的數據庫芜抒,以下是連接的代碼

#-*- coding=utf-8 -*-
import pymysql
conn=pymysql.connect(host='localhost',port=3306,user='root',password='xxx',db='test',charset='UTF8')
cur=conn.cursor()
cur.execute('insert into user (userid,username) values(1,\'ou\')')
cur.close()
conn.commit()
conn.close()

2.使用SQLAlchemy

在Python中珍策,最有名的ORM框架是SQLAlchemy。我們來看看SQLAlchemy的用法宅倒。
首先通過pip安裝SQLAlchemy:

pip install sqlalchemy

然后攘宙,利用上次我們在MySQL的test數據庫中創(chuàng)建的user表,用SQLAlchemy來試試:
第一步拐迁,導入SQLAlchemy蹭劈,并初始化DBSession:

# 導入:
from sqlalchemy import Column, String, create_enginefrom sqlalchemy.orm 
import sessionmakerfrom sqlalchemy.ext.declarative 
import declarative_base
# 創(chuàng)建對象的基類:
Base = declarative_base()
# 定義User對象:
class User(Base): 
  # 表的名字: 
  __tablename__ = 'user' 
  # 表的結構: 
  id = Column(String(20), primary_key=True) 
  name = Column(String(20))
  # 初始化數據庫連接:
  engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
  # 創(chuàng)建DBSession類型:
  DBSession = sessionmaker(bind=engine)

以上代碼完成SQLAlchemy的初始化和具體每個表的class定義。如果有多個表线召,就繼續(xù)定義其他class铺韧,例如School:

class School(Base):
   __tablename__ = 'school' 
  id = ... 
  name = ...

create_engine()用來初始化數據庫連接。SQLAlchemy用一個字符串表示連接信息:'數據庫類型+數據庫驅動名稱://用戶名:口令@機器地址:端口號/數據庫名'

你只需要根據需要替換掉用戶名缓淹、口令等信息即可哈打。
下面,我們看看如何向數據庫表中添加一行記錄讯壶。
由于有了ORM料仗,我們向數據庫表中添加一行記錄,可以視為添加一個User
對象:

# 創(chuàng)建session對象:
session = DBSession()
# 創(chuàng)建新User對象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到數據庫:
session.commit()
# 關閉
session:session.close()

可見伏蚊,關鍵是獲取session立轧,然后把對象添加到session,最后提交并關閉躏吊。DBSession對象可視為當前數據庫連接氛改。

3.HTTP協(xié)議

協(xié)議是指計算機通信網絡中兩臺計算機之間進行通信所必須共同遵守的規(guī)定或規(guī)則,超文本傳輸協(xié)議(HTTP)是一種通信協(xié)議比伏,它允許將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器
目前我們使用的是HTTP/1.1 版本
URL詳解
  URL(Uniform Resource Locator) 地址用于描述一個網絡上的資源胜卤, 基本格式如下
schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]
  scheme 指定低層使用的協(xié)議(例如:http, https, ftp)
  host HTTP服務器的IP地址或者域名
  port# HTTP服務器的默認端口是80,這種情況下端口號可以省略凳怨。如果使用了別的端口瑰艘,必須指明,例如 http://www.cnblogs.com:8080/
  path 訪問資源的路徑
  url-params
  query-string 發(fā)送給http服務器的數據
  anchor- 錨
HTTP協(xié)議是無狀態(tài)的
  http協(xié)議是無狀態(tài)的肤舞,同一個客戶端的這次請求和上次請求是沒有對應關系紫新,對http服務器來說,它并不知道這兩個請求來自同一個客戶端李剖。 為了解決這個問題芒率, Web程序引入了Cookie機制來維護狀態(tài).
  HTTP消息的結構
  先看Request 消息的結構, Request 消息分為3部分篙顺,第一部分叫請求行偶芍, 第二部分叫http header, 第三部分是body. header和body之間有個空行充择, 結構如下圖


  第一行中的Method表示請求方法,比如"POST"匪蟀,"GET"椎麦, Path-to-resoure表示請求的資源, Http/version-number 表示HTTP協(xié)議的版本號
  當使用的是"GET" 方法的時候材彪, body是為空的
Get和Post方法的區(qū)別
  Http協(xié)議定義了很多與服務器交互的方法观挎,最基本的有4種,分別是GET,POST,PUT,DELETE. 一個URL地址用于描述一個網絡上的資源段化,而HTTP中的GET, POST, PUT, DELETE就對應著對這個資源的查嘁捷,改,增显熏,刪4個操作雄嚣。 我們最常見的就是GET和POST了。GET一般用于獲取/查詢資源信息喘蟆,而POST一般用于更新資源信息.
  我們看看GET和POST的區(qū)別
  1. GET提交的數據會放在URL之后缓升,以?分割URL和傳輸數據,參數之間以&相連履肃,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的Body中.
  2. GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制)仔沿,而POST方法提交的數據沒有限制.
  3. GET方式需要使用Request.QueryString來取得變量的值坐桩,而POST方式通過Request.Form來獲取變量的值尺棋。
  4. GET方式提交數據,會帶來安全問題绵跷,比如一個登錄頁面膘螟,通過GET方式提交數據時,用戶名和密碼將出現(xiàn)在URL上碾局,如果頁面可以被緩存或者其他人可以訪問這臺機器荆残,就可以從歷史記錄獲得該用戶的賬號和密碼.
  狀態(tài)碼
  Response 消息中的第一行叫做狀態(tài)行,由HTTP協(xié)議版本號净当, 狀態(tài)碼内斯, 狀態(tài)消息 三部分組成。
  狀態(tài)碼用來告訴HTTP客戶端像啼,HTTP服務器是否產生了預期的Response.
  HTTP/1.1中定義了5類狀態(tài)碼俘闯, 狀態(tài)碼由三位數字組成,第一個數字定義了響應的類別
  1XX 提示信息 - 表示請求已被成功接收忽冻,繼續(xù)處理
  2XX 成功 - 表示請求已被成功接收真朗,理解,接受
  3XX 重定向 - 要完成請求必須進行更進一步的處理
  4XX 客戶端錯誤 - 請求有語法錯誤或請求無法實現(xiàn)
  5XX 服務器端錯誤 - 服務器未能實現(xiàn)合法的請求
  看看一些常見的狀態(tài)碼
  200 OK
  最常見的就是成功響應狀態(tài)碼200了僧诚, 這表明該請求被成功地完成遮婶,所請求的資源發(fā)送回客戶端
302 Found
  重定向蝗碎,新的URL會在response中的Location中返回,瀏覽器將會使用新的URL發(fā)出新的Request旗扑。
304 Not Modified 代表上次的文檔已經被緩存了蹦骑, 還可以繼續(xù)使用
400 Bad Request 客戶端請求與語法錯誤,不能被服務器所理解
403 Forbidden 服務器收到請求臀防,但是拒絕提供服務
404 Not Found 請求資源不存在(輸錯了URL)
500 Internal Server Error 服務器發(fā)生了不可預期的錯誤
503 Server Unavailable 服務器當前不能處理客戶端的請求脊串,一段時間后可能恢復正常

4.WSGI接口

了解了HTTP協(xié)議和HTML文檔,我們其實就明白了一個Web應用的本質就是:
瀏覽器發(fā)送一個HTTP請求清钥;

服務器收到請求琼锋,生成一個HTML文檔;

服務器把HTML文檔作為HTTP響應的Body發(fā)送給瀏覽器祟昭;

瀏覽器收到HTTP響應缕坎,從HTTP Body取出HTML文檔并顯示。

所以篡悟,最簡單的Web應用就是先把HTML用文件保存好谜叹,用一個現(xiàn)成的HTTP服務器軟件,接收用戶請求搬葬,從文件中讀取HTML荷腊,返回。Apache急凰、Nginx女仰、Lighttpd等這些常見的靜態(tài)服務器就是干這件事情的。
如果要動態(tài)生成HTML抡锈,就需要把上述步驟自己來實現(xiàn)疾忍。不過,接受HTTP請求床三、解析HTTP請求一罩、發(fā)送HTTP響應都是苦力活,如果我們自己來寫這些底層代碼撇簿,還沒開始寫動態(tài)HTML呢聂渊,就得花個把月去讀HTTP規(guī)范。
正確的做法是底層代碼由專門的服務器軟件實現(xiàn)四瘫,我們用Python專注于生成HTML文檔汉嗽。因為我們不希望接觸到TCP連接、HTTP原始請求和響應格式莲组,所以诊胞,需要一個統(tǒng)一的接口,讓我們專心用Python編寫Web業(yè)務。
這個接口就是WSGI:Web Server Gateway Interface撵孤。
WSGI接口定義非常簡單迈着,它只要求Web開發(fā)者實現(xiàn)一個函數,就可以響應HTTP請求邪码。我們來看一個最簡單的Web版本的“Hello, web!”:

def application(environ, start_response): 
  start_response('200 OK', [('Content-Type', 'text/html')]) 
  return [b'<h1>Hello, web!</h1>']

上面的application()函數就是符合WSGI標準的一個HTTP處理函數裕菠,它接收兩個參數:
environ:一個包含所有HTTP請求信息的dict
對象;
start_response:一個發(fā)送HTTP響應的函數闭专。

在application()函數中奴潘,調用:

start_response('200 OK', [('Content-Type', 'text/html')])

就發(fā)送了HTTP響應的Header,注意Header只能發(fā)送一次影钉,也就是只能調用一次start_response()函數画髓。start_response()函數接收兩個參數,一個是HTTP響應碼平委,一個是一組list表示的HTTP Header奈虾,每個Header用一個包含兩個str的tuple表示。通常情況下廉赔,都應該把Content-Type頭發(fā)送給瀏覽器肉微。其他很多常用的HTTP Header也應該發(fā)送。然后蜡塌,函數的返回值

b'<h1>Hello, web!</h1>'

將作為HTTP響應的Body發(fā)送給瀏覽器碉纳。
有了WSGI,我們關心的就是如何從environ這個dict對象拿到HTTP請求信息馏艾,然后構造HTML劳曹,通過start_response()發(fā)送Header,最后返回Body攒至。
整個application()函數本身沒有涉及到任何解析HTTP的部分厚者,也就是說躁劣,底層代碼不需要我們自己編寫迫吐,我們只負責在更高層次上考慮如何響應請求就可以了。
不過账忘,等等志膀,這個application()函數怎么調用?如果我們自己調用鳖擒,兩個參數environ和start_response我們沒法提供溉浙,返回的bytes也沒法發(fā)給瀏覽器。所以application()函數必須由WSGI服務器來調用蒋荚。有很多符合WSGI規(guī)范的服務器戳稽,我們可以挑選一個來用。但是現(xiàn)在,我們只想盡快測試一下我們編寫的application()函數真的可以把HTML輸出到瀏覽器惊奇,所以互躬,要趕緊找一個最簡單的WSGI服務器,把我們的Web應用程序跑起來颂郎。
好消息是Python內置了一個WSGI服務器艰管,這個模塊叫wsgiref疚鲤,它是用純Python編寫的WSGI服務器的參考實現(xiàn)。所謂“參考實現(xiàn)”是指該實現(xiàn)完全符合WSGI標準,但是不考慮任何運行效率歹鱼,僅供開發(fā)和測試使用。
運行WSGI服務我們先編寫hello.py實現(xiàn)Web應用程序的WSGI處理函數:

# hello.py
def application(environ, start_response): 
  start_response('200 OK', [('Content-Type', 'text/html')]) 
  return [b'<h1>Hello, web!</h1>']

然后赔硫,再編寫一個server.py滨达,負責啟動WSGI服務器,加載application()
函數:

# server.py
# 從wsgiref模塊導入:
from wsgiref.simple_server import make_server
# 導入我們自己編寫的application函數:
from hello import application
# 創(chuàng)建一個服務器陨献,IP地址為空咙俩,端口是8000,處理函數是application:
httpd = make_server('', 8000, application)
print('Serving HTTP on port 8000...')
# 開始監(jiān)聽HTTP請求:
httpd.serve_forever()

確保以上兩個文件在同一個目錄下湿故,然后在命令行輸入python server.py
來啟動WSGI服務器:
注意:如果8000端口已被其他程序占用阿趁,啟動將失敗,請修改成其他端口坛猪。

啟動成功后脖阵,打開瀏覽器,輸入http://localhost:8000/墅茉,就可以看到結果了:
如果你覺得這個Web應用太簡單了命黔,可以稍微改造一下,從environ
里讀取PATH_INFO
就斤,這樣可以顯示更加動態(tài)的內容:

# hello.py
def application(environ, start_response): 
  start_response('200 OK', [('Content-Type', 'text/html')]) 
  body = '<h1>Hello, %s!</h1>' % (environ['PATH_INFO'][1:] or 'web')     
  return [body.encode('utf-8')]

你可以在地址欄輸入用戶名作為URL的一部分悍募,將返回Hello, xxx!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市洋机,隨后出現(xiàn)的幾起案子坠宴,更是在濱河造成了極大的恐慌,老刑警劉巖绷旗,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喜鼓,死亡現(xiàn)場離奇詭異,居然都是意外死亡衔肢,警方通過查閱死者的電腦和手機庄岖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來角骤,“玉大人隅忿,你說我怎么就攤上這事。” “怎么了背桐?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵刘陶,是天一觀的道長。 經常有香客問我牢撼,道長匙隔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任熏版,我火速辦了婚禮纷责,結果婚禮上,老公的妹妹穿的比我還像新娘撼短。我一直安慰自己再膳,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布曲横。 她就那樣靜靜地躺著喂柒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪禾嫉。 梳的紋絲不亂的頭發(fā)上灾杰,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音熙参,去河邊找鬼艳吠。 笑死,一個胖子當著我的面吹牛孽椰,可吹牛的內容都是我干的昭娩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼黍匾,長吁一口氣:“原來是場噩夢啊……” “哼栏渺!你這毒婦竟也來了?” 一聲冷哼從身側響起锐涯,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤磕诊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后全庸,有當地人在樹林里發(fā)現(xiàn)了一具尸體秀仲,經...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年壶笼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雁刷。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡覆劈,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情责语,我是刑警寧澤炮障,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站坤候,受9級特大地震影響胁赢,放射性物質發(fā)生泄漏。R本人自食惡果不足惜白筹,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一智末、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧徒河,春花似錦系馆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至代兵,卻和暖如春尼酿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背植影。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工谓媒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人何乎。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓句惯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親支救。 傳聞我的和親對象是個殘疾皇子抢野,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內容