自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Dataset基于SQLAlchemy的便利工具

數(shù)據(jù)庫(kù) 開(kāi)發(fā)
數(shù)據(jù)集使得數(shù)據(jù)庫(kù)中的數(shù)據(jù)讀取和寫(xiě)入數(shù)據(jù)就像閱讀和編寫(xiě)JSON文件一樣簡(jiǎn)單。Dataset對(duì)于操作JSON、CSV文件、NoSQL非常好用。

[[206839]]

數(shù)據(jù)集使得數(shù)據(jù)庫(kù)中的數(shù)據(jù)讀取和寫(xiě)入數(shù)據(jù)就像閱讀和編寫(xiě)JSON文件一樣簡(jiǎn)單。

Dataset對(duì)于操作JSON、CSV文件、NoSQL非常好用。

  1. import dataset 

連接MySQL數(shù)據(jù)庫(kù):

  1. db = dataset.connect('mysql://username:password@10.10.10.10/ctf?charset=utf8'

用戶名:username,密碼:password,數(shù)據(jù)庫(kù)地址(地址+端口):10.10.10.10,database名: ctf

連接SQLite數(shù)據(jù)庫(kù):

  1. db = dataset.connect('sqlite:///ctf.db'

連接PostgreSQL數(shù)據(jù)庫(kù):

  1. db = dataset.connect('postgresql://scott:tiger@localhost:5432/mydatabase'

一定要注意指定字符編碼

  1. table = db['city'] #(選擇city表) 
  2.  
  3. user = table('name') # 找出表中'name'列屬性所有數(shù)據(jù) 
  4.  
  5. res = db.query('select name from table limit 10') # 如果不需要查看全部數(shù)據(jù)的話***用limit,因?yàn)槿繑?shù)據(jù)的載入非常非常耗時(shí)間 
  6.  
  7. for x in res: 
  8.  
  9. print x['name'] # 選name字段的數(shù)據(jù) 
  10.  
  11. table.insert(dict(name='John Doe', age=37)) 
  12.  
  13. table.insert(dict(name='Jane Doe', age=34, gender='female')) 
  14.  
  15. john = table.find_one(name='John Doe' 

在數(shù)據(jù)庫(kù)中查找是否有同時(shí)滿足多個(gè)條件的數(shù)據(jù):table.find_one(屬性1=屬性值1, 屬性2=屬性值2, …)

注:find_one速度很慢

插入數(shù)據(jù)

dataset會(huì)根據(jù)輸入自動(dòng)創(chuàng)建表和字段名

  1. table = db['user'
  2.  
  3. # 或者table = db.get_table('user'
  4.  
  5. table.insert(dict(name='John Doe', age=46, country='China')) 
  6.  
  7. table.insert(dict(name='Jane Doe', age=37, country='France', gender='female')) 
  8.  
  9. # 主鍵id自動(dòng)生成  

更新數(shù)據(jù)

  1. table.update(dict(name='John Doe', age=47), ['name']) 
  2.  
  3. # 第二個(gè)參數(shù)相當(dāng)于sql update語(yǔ)句中的where,用來(lái)過(guò)濾出需要更新的記錄  

事務(wù)操作

事務(wù)操作可以簡(jiǎn)單的使用上下文管理器來(lái)實(shí)現(xiàn),出現(xiàn)異常,將會(huì)回滾

  1. with dataset.connect() as tx: 
  2.  
  3. tx['user'].insert(dict(name='John Doe', age=46, country='China')) 
  4.  
  5. # 相當(dāng)于: 
  6.  
  7. db = dataset.connect() 
  8.  
  9. db.begin() 
  10.  
  11. try: 
  12.  
  13. db['user'].insert(dict(name='John Doe', age=46, country='China')) 
  14.  
  15. db.commit() 
  16.  
  17. except
  18.  
  19. db.rollback() 
  20.  
  21. # 也可以嵌套使用: 
  22.  
  23. db = dataset.connect() 
  24.  
  25. with db as tx1: 
  26.  
  27. tx1['user'].insert(dict(name='John Doe', age=46, country='China')) 
  28.  
  29. with db as tx2: 
  30.  
  31. tx2['user'].insert(dict(name='Jane Doe', age=37, country='France', gender='female'))  

從表獲取數(shù)據(jù)

  1. users = db['user'].all() 
  2.  
  3. for user in db['user']: 
  4.  
  5. # print(user['age']) 
  6.  
  7. # chinese_users = user.find(country='China'
  8.  
  9. john = user.find_one(name='John Doe' 

獲取非重復(fù)數(shù)據(jù)

  1. db['user'].distinct('country'

刪除記錄

  1. table.delete(place='Berlin'

執(zhí)行SQL語(yǔ)句

  1. result = db.query('SELECT country, COUNT(*) c FROM user GROUP BY country'
  2.  
  3. for row in result: 
  4.  
  5. print(row['country'], row['c'])  

導(dǎo)出數(shù)據(jù)

  1. result = db['users'].all() 
  2.  
  3. dataset.freeze(result, format='json', filename='users.json' 

JSON

JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式,非常易于人閱讀和編寫(xiě)。

  1. import json 

json.dumps 將 Python 對(duì)象編碼成 JSON 字符串

json.loads 將已編碼的 JSON 字符串解碼為 Python 對(duì)象

MySQL數(shù)據(jù)庫(kù):

分類(lèi)表-categories,包括類(lèi)別web,reversing,crypto(加解密),mic等

題目表-tasks,包括題目id,題目名,flag,分值,文件&地址,題目等級(jí),題目詳細(xì)描述

flag表-flag,包括題目id,用戶id,得分,時(shí)間戳

用戶表-users,包括用戶id,用戶名,密碼

題目分類(lèi)表-cat_task,包括題目id,題目類(lèi)別id

flag表中每條數(shù)據(jù)由于是有題目ID task_id和用戶ID user_id來(lái)共同確認(rèn)的,所以采用復(fù)合主鍵:primary key (task_id,user_id)

聯(lián)合主鍵和復(fù)合主鍵的區(qū)別

python裝飾器

Decorator通過(guò)返回包裝對(duì)象實(shí)現(xiàn)間接調(diào)用,以此插入額外邏輯

https://www.zhihu.com/question/26930016

wraps本身也是一個(gè)裝飾器,它能把原函數(shù)的元信息拷貝到裝飾器函數(shù)中,這使得裝飾器函數(shù)也有和原函數(shù)一樣的元信息了

  1. from functools import wraps 
  2.  
  3. def logged(func): 
  4.  
  5. @wraps(func) 
  6.  
  7. def with_logging(*args,**kwargs): 
  8.  
  9. print func.__name__ + "was called" 
  10.  
  11. return func(*args,**kwargs) 
  12.  
  13. return with_logging 
  14.  
  15.   
  16.  
  17. @logged 
  18.  
  19. def f(x): 
  20.  
  21. """does some math""" 
  22.  
  23. return x + x * x 
  24.  
  25.   
  26.  
  27. print f.__name__ # prints 'f' 
  28.  
  29. print f.__doc__ # prints 'does some math'  

web框架采用flask

  1. from flask import Flask 

引入Flask類(lèi),F(xiàn)lask類(lèi)實(shí)現(xiàn)了一個(gè)WSGI(Web Server Gateway Interface)應(yīng)用

  1. app = Flask(__name__) 

app是Flask的實(shí)例,它接收包或者模塊的名字作為參數(shù),但一般都是傳遞__name__

  1. @app.route('/'
  2.  
  3. def hello_world(): 
  4.  
  5. return 'Hello World!'  

使用app.route裝飾器會(huì)將URL和執(zhí)行的視圖函數(shù)的關(guān)系保存到app.url_map屬性上。處理URL和視圖函數(shù)的關(guān)系的程序就是路由,這里的視圖函數(shù)就是hello_world

  1. if __name__ == '__main__'
  2.  
  3. app.run(host='0.0.0.0',port=9000)  

使用這個(gè)判斷可以保證當(dāng)其他文件引用這個(gè)文件的時(shí)候(例如from hello import app)不會(huì)執(zhí)行這個(gè)判斷內(nèi)的代碼,也就是不會(huì)執(zhí)行app.run函數(shù)。

執(zhí)行app.run就可以啟動(dòng)服務(wù)了。默認(rèn)Flask只監(jiān)聽(tīng)虛擬機(jī)的本地127.0.0.1這個(gè)地址,端口為5000。而我們對(duì)虛擬機(jī)做的端口轉(zhuǎn)發(fā)端口是9000,所以需要制定host和port參數(shù),0.0.0.0表示監(jiān)聽(tīng)所有地址,這樣就可以在本機(jī)訪問(wèn)了。

服務(wù)器啟動(dòng)后,會(huì)調(diào)用werkzeug.serving.run_simple進(jìn)入輪詢(xún),默認(rèn)使用單進(jìn)程單線程的werkzeug.serving.BaseWSGIServer處理請(qǐng)求,實(shí)際上還是使用標(biāo)準(zhǔn)庫(kù)BaseHTTPServer.HTTPServer,通過(guò)select.select做0.5秒的while TRUE的事件輪詢(xún)。當(dāng)我們?cè)L問(wèn)http://127.0.0.1:9000/,通過(guò)app.url_map找到注冊(cè)的/這個(gè)URL模式,就找到了對(duì)應(yīng)的hello_world函數(shù)執(zhí)行,返回hello world!,狀態(tài)碼為200。如果訪問(wèn)一個(gè)不存在的路徑,如訪問(wèn)http://127.0.0.1:9000/a,Flask找不到對(duì)應(yīng)的模式,就會(huì)向?yàn)g覽器返回Not Found,狀態(tài)碼為404

flask中jsonify的作用

jsonify的作用實(shí)際上就是將我們傳入的json形式數(shù)據(jù)序列化成為json字符串,作為響應(yīng)的body,并且設(shè)置響應(yīng)的Content-Type為application/json,構(gòu)造出響應(yīng)返回至客戶端

效果等于json.dumps

jsonify的Content-Type字段值為application/json

json.dumps的Content-Type字段值為text/html

修改flask中靜態(tài)文件夾

修改的flask默認(rèn)的static文件夾只需要在創(chuàng)建Flask實(shí)例的時(shí)候,把static_folder和static_url_path參數(shù)設(shè)置為空字符串即可。

app = Flask(__name__, static_folder=”, static_url_path=”)

訪問(wèn)的時(shí)候用url_for函數(shù),res文件夾和static文件夾同一級(jí):

url_for(‘static’, filename=’res/favicon.ico’)

werkzeug

werkzeug是一個(gè)WSGI工具包,可以作為一個(gè)Web框架的底層庫(kù)。它封裝好了很多Web框架的東西,例如 Request,Response等等。Flask框架就是一Werkzeug 為基礎(chǔ)開(kāi)發(fā)的

generate_password_hash(password)

將用戶輸入的明文密碼加密成密文進(jìn)行存儲(chǔ)

密碼加鹽哈希函數(shù)。用來(lái)將明文密碼加密,返回加密后的密文,用來(lái)進(jìn)行用戶注冊(cè)

函數(shù)定義: 

werkzeug.security.generate_password_hash(password, method='pbkdf2:sha1', salt_length=8)

密文格式:method$salt$hash

password: 明文密碼

method: 哈希的方式(需要是hashlib庫(kù)支持的),格式為

pbpdf2:<method>[:iterations]。參數(shù)說(shuō)明:

method:哈希的方式,一般為SHA1,

iterations:(可選參數(shù))迭代次數(shù),默認(rèn)為1000。 

slat_length: 鹽值的長(zhǎng)度,默認(rèn)為8

check_password_hash(hash,password)

驗(yàn)證經(jīng)過(guò)generate_password_hash哈希的密碼,將明文和密文進(jìn)行比較,查看是否一致,用來(lái)驗(yàn)證用戶登錄

函數(shù)定義: 

werkzeug.security.check_password_hash(pwhash, password)

pwhash: generate_password_hash生成的哈希字符串 

password: 需要驗(yàn)證的明文密碼

flask中的session

  1. rom flask import session 
  2.  
  3. user = db['users'].find_one(username=username) 
  4.  
  5. session['user_id'] = user['id' 

由于使用了session,所以需要設(shè)置一個(gè)secret_key用來(lái)做一些模塊的hash

Flask Web Development 中的內(nèi)容:

SECRET_KEY配置變量是通用密鑰,可在Flask和多個(gè)第三方擴(kuò)展中使用。如其名所示,加密的強(qiáng)度取決于變量值的機(jī)密度。不同的程序要使用不同的密鑰,而且要保證其他人不知道你所用的字符串。

SECRET_KEY的作用主要是提供一個(gè)值做各種HASH, 是在其加密過(guò)程中作為算法的一個(gè)參數(shù)(salt或其他)。所以這個(gè)值的復(fù)雜度也就影響到了數(shù)據(jù)傳輸和存儲(chǔ)時(shí)的復(fù)雜度。

flask 變量規(guī)則

要給URL添加變量部分,你可以把這些特殊的字段標(biāo)記為<variable_name>, 這個(gè)部分將會(huì)作為命名參數(shù)傳遞到你的函數(shù)。規(guī)則可以用<converter:variable_name>指定一個(gè)可選的轉(zhuǎn)換器

  1. @route('/hello/<name>'
  2.  
  3. def index(name): 
  4.  
  5. return '<b>Hello {{name}}</b>!'  

數(shù)據(jù)庫(kù)查詢(xún)

對(duì)dataset的數(shù)據(jù)查詢(xún),使用冒號(hào)來(lái)為變量傳參。

select f.task_id from flags f where f.user_id = :user_id”’,user_id=session[‘user_id’])

模板渲染

使用render_template方法來(lái)渲染模板。將模板名和你想作為關(guān)鍵字的參數(shù)傳入模板的變量

MySQL

IFNULL(expr1,expr2)

如果expr1不是NULL,IFNULL()返回expr1,否則它返回expr2。

IFNULL()返回一個(gè)數(shù)字或字符串值,取決于它被使用的上下文環(huán)境。

max函數(shù)是用來(lái)找出記錄集中***值的記錄

  1. 對(duì)于left join,不管on后面跟什么條件,左表的數(shù)據(jù)全部查出來(lái),因此要想過(guò)濾需把條件放到where后面
  2. 對(duì)于inner join,滿足on后面的條件表的數(shù)據(jù)才能查出,可以起到過(guò)濾作用。也可以把條件放到where后面

在使用left jion時(shí),on和where條件的區(qū)別如下:

  1. on條件是在生成臨時(shí)表時(shí)使用的條件,它不管on中的條件是否為真,都會(huì)返回左邊表中的記錄。
  2. where條件是在臨時(shí)表生成好后,再對(duì)臨時(shí)表進(jìn)行過(guò)濾的條件。這時(shí)已經(jīng)沒(méi)有l(wèi)eft join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過(guò)濾掉。

order by的用法 

使用order by,一般是用來(lái),依照查詢(xún)結(jié)果的某一列(或多列)屬性,進(jìn)行排序(升序:ASC;降序:DESC;默認(rèn)為升序)。

當(dāng)排序列含空值時(shí):

ASC:排序列為空值的元組***顯示。

DESC:排序列為空值的元組***顯示。

可以把null值看做無(wú)窮大 

select * from s order by sno desc, sage asc

group by的用法 

group by按照查詢(xún)結(jié)果集中的某一列(或多列),進(jìn)行分組,值相等的為一組

1、細(xì)化集函數(shù)(count,sum,avg,max,min)的作用對(duì)象:

未對(duì)查詢(xún)結(jié)果分組,集函數(shù)將作用于整個(gè)查詢(xún)結(jié)果。

對(duì)查詢(xún)結(jié)果分組后,集函數(shù)將分別作用于每個(gè)組。

SELECT cno,count(sno) from sc group by cno

2、GROUP BY子句的作用對(duì)象是查詢(xún)的中間結(jié)果表

分組方法:按指定的一列或多列值分組,值相等的為一組。

使用GROUP BY子句后,SELECT子句的列名列表中只能出現(xiàn)分組屬性(比如:sno)和集函數(shù)(比如:count())

select sno,count(cno) from sc group by sno

3、多個(gè)列屬性進(jìn)行分組

select cno,grade,count(cno) from sc group by cno,grade

4、使用HAVING短語(yǔ)篩選最終輸出結(jié)果

只有滿足HAVING短語(yǔ)指定條件的組才輸出。

HAVING短語(yǔ)與WHERE子句的區(qū)別:作用對(duì)象不同。

1、WHERE子句作用于基表或視圖,從中選擇滿足條件的元組。

2、HAVING短語(yǔ)作用于組,從中選擇滿足條件的組

select sno from sc group by sno having count(cno)>3

 

select sno,count(cno) from sc where grade>60 group by sno having count(cno)>3

MySQL的左連接、右連接、等值連接

1.左連接(left join )

  1. select m.columnname……,n.* columnname….. 
  2.  
  3. from left_table m left join right_table n on m.columnname_join=n.columnname_join and n.columnname=xxx 
  4.  
  5. where m.columnname=xxx…..  

ON是連接條件,用于把2表中等值的記錄連接在一起,但是不影響記錄集的數(shù)量。若是表left_table中的某記錄,無(wú)法在表right_table找到對(duì)應(yīng)的記錄,則此記錄依然顯示在記錄集中,只是表right_table需要在查詢(xún)顯示的列的值用NULL替代;

ON連接條件中表n.columnname=xxx用于控制right_table表是否有符合要求的列值還是用NULL替換的方式顯示在查詢(xún)列中,不影響記錄集的數(shù)量;

WHERE字句控制記錄是否符合查詢(xún)要求,不符合則過(guò)濾掉

2.右連接(right join)

  1. select m.columnname……,n.* columnname….. 
  2.  
  3. from left_table m right join right_table n on m. columnname_join=n. columnname_join and m. columnname=xxx 
  4.  
  5. where n.columnname=xxx…..  

3.等值連接

  1. select m.columnname……,n.* columnname….. 
  2.  
  3. from left_table m [innerjoin right_table n on m. columnname_join=n. columnname_join 
  4.  
  5. where m.columnname=xxx….. and n.columnname=xxx….  

或者

  1. select m.columnname……,n.* columnname….. 
  2.  
  3. from left_table m , right_table n 
  4.  
  5. where m. columnname_join=n. columnname_join and 
  6.  
  7. m.columnname=xxx….. and n.columnname=xxx….  

ON是連接條件,不再與左連接或右連接的功效一樣,除了作為2表記錄匹配的條件外,還會(huì)起到過(guò)濾記錄的作用,若left_table中記錄無(wú)法在right_table中找到對(duì)應(yīng)的記錄,則會(huì)被過(guò)濾掉;

WHERE字句,不管是涉及表left_table、表right_table上的限制條件,還是涉及2表連接的條件,都會(huì)對(duì)記錄集起到過(guò)濾作用,把不符合要求的記錄刷選掉;

jinja2獲取循環(huán)索引

jinja2獲取循環(huán){% for i in n %}的索引使用loop.index

  1. {% for i in names %} 
  2.  
  3. <tr> 
  4.  
  5. <td>{{ loop.index }}</td> //當(dāng)前是第x條 
  6.  
  7. <td>{{ i.name }}</td> 
  8.  
  9. </tr> 
  10.  
  11. {% endfor %}  

flask 重定向和錯(cuò)誤

可以用redirect()函數(shù)把用戶重定向到其它地方。放棄請(qǐng)求并返回錯(cuò)誤代碼,用abort()函數(shù)。

  1. from flask import abort, redirect, url_for 
  2.  
  3. @app.route('/'
  4.  
  5. def index(): 
  6.  
  7. return redirect(url_for('login')) 
  8.  
  9. @app.route('/login'
  10.  
  11. def login(): 
  12.  
  13. abort(401) 
  14.  
  15. this_is_never_executed()  

默認(rèn)情況下,錯(cuò)誤代碼會(huì)顯示一個(gè)黑白的錯(cuò)誤頁(yè)面。如果你要定制錯(cuò)誤頁(yè)面,可以使用errorhandler()

裝飾器:

  1. from flask import render_template 
  2.  
  3. @app.errorhandler(404) 
  4.  
  5. def page_not_found(error): 
  6.  
  7. return render_template('page_not_found.html'), 404  

注意 render_template()調(diào)用之后的 404 。這告訴Flask,該頁(yè)的錯(cuò)誤代碼是404 ,即沒(méi)有找到。默認(rèn)為200,也就是一切正常。

flask CSRF防護(hù)機(jī)制

  1. @app.before_request 
  2.  
  3. def csrf_protect(): 
  4.  
  5. if request.method == "POST"
  6.  
  7. token = session.pop('_csrf_token', None) 
  8.  
  9. if not token or token != request.form.get('_csrf_token'): 
  10.  
  11. abort(403) 
  12.  
  13. def some_random_string(): 
  14.  
  15. return hashlib.sha256(os.urandom(16).hexdigest()) 
  16.  
  17. def generate_csrf_token(): 
  18.  
  19. if '_csrf_token' not in session: 
  20.  
  21. session['_csrf_token'] = some_random_string() 
  22.  
  23. return session['_csrf_token' 

在flask的全局變量里面注冊(cè) 上面那個(gè)生成隨機(jī)token的函數(shù)

app.jinja_env.globals[‘csrf_token’] = generate_csrf_token

在網(wǎng)頁(yè)的模板是這么引入的

  1. <form method=post action=""
  2.  
  3. <input name=_csrf_token type=hidden value="{{ csrf_token() }}" 

flask上下文處理器

Flask 上下文處理器自動(dòng)向模板的上下文中插入新變量。上下文處理器在模板渲染之前運(yùn)行,并且可以在模板上下文中插入新值。上下文處理器是一個(gè)返回字典的函數(shù),這個(gè)字典的鍵值最終將傳入應(yīng)用中所有模板的上下文:

  1. @app.context_processor 
  2.  
  3. def inject_user(): 
  4.  
  5. return dict(user=g.user 

上面的上下文處理器使得模板可以使用一個(gè)名為user值為g.user的變量。不過(guò)這個(gè)例子不是很有意思,因?yàn)間在模板中本來(lái)就是可用的,但它解釋了上下文處理器是如何工作的。

變量不僅限于值,上下文處理器也可以使某個(gè)函數(shù)在模板中可用(由于Python允許傳遞函數(shù)):

  1. @app.context_processor 
  2.  
  3. def utility_processor(): 
  4.  
  5. def format_price(amount, currency=u'€'): 
  6.  
  7. return u'{0:.2f}{1}.format(amount, currency) 
  8.  
  9. return dict(format_price=format_price)  

上面的上下文處理器使得format_price函數(shù)在所有模板中可用:

{{ format_price(0.33) }}

日志記錄

handler = logging.FileHandler(‘flask.log’, encoding=’UTF-8′)

1、請(qǐng)求之前設(shè)置requestId并記錄日志

每個(gè)URL請(qǐng)求之前,定義requestId并綁定到g

  1. @app.before_request 
  2.  
  3. def before_request(): 
  4.  
  5. g.requestId = gen_requestId() 
  6.  
  7. logger.info("Start Once Access, and this requestId is %s" % g.requestId)  

2、請(qǐng)求之后添加響應(yīng)頭與記錄日志

每次返回?cái)?shù)據(jù)中,帶上響應(yīng)頭,包含API版本和本次請(qǐng)求的requestId,以及允許所有域跨域訪問(wèn)API, 記錄訪問(wèn)日志 

  1. @app.after_request 
  2.  
  3. def add_header(response): 
  4.  
  5. response.headers["X-SaintIC-Media-Type"] = "saintic.v1" 
  6.  
  7. response.headers["X-SaintIC-Request-Id"] = g.requestId 
  8.  
  9. response.headers["Access-Control-Allow-Origin"] = "*" 
  10.  
  11. logger.info(json.dumps({ 
  12.  
  13. "AccessLog": { 
  14.  
  15. "status_code": response.status_code, 
  16.  
  17. "method": request.method, 
  18.  
  19. "ip": request.headers.get('X-Real-Ip', request.remote_addr), 
  20.  
  21. "url": request.url, 
  22.  
  23. "referer": request.headers.get('Referer'), 
  24.  
  25. "agent": request.headers.get("User-Agent"), 
  26.  
  27. "requestId": str(g.requestId), 
  28.  
  29.  
  30.  
  31. )) 
  32.  
  33. return response  

basicConfig方法可以滿足你在絕大多數(shù)場(chǎng)景下的使用需求,但是basicConfig有一個(gè)很大的缺點(diǎn)。調(diào)用basicConfig其實(shí)是給root logger添加了一個(gè)handler(FileHandler ),這樣當(dāng)你的程序和別的使用了 logging的第三方模塊一起工作時(shí),會(huì)影響第三方模塊的logger行為。這是由logger的繼承特性決定的

  1. logging.basicConfig(level=logging.DEBUG, 
  2.  
  3. format='%(asctime)s %(levelname)s %(message)s'
  4.  
  5. datefmt='%a, %d %b %Y %H:%M:%S'
  6.  
  7. filename='logs/pro.log'
  8.  
  9. filemode='w'
  10.  
  11.   
  12.  
  13. logging.debug('dddddddddd' 

MySQL字符編碼

除了設(shè)置數(shù)據(jù)庫(kù)的之外,由于dataset默認(rèn)創(chuàng)建數(shù)據(jù)庫(kù)和表的字符集不是utf8,所以需要自己設(shè)置,否則會(huì)中文亂碼,所以需要修改表的字符集

  1. my.cnf 
  2.  
  3. [client] 
  4.  
  5. default-character-set=utf8 
  6.  
  7. [mysqld] 
  8.  
  9. character-set-server=utf8 
  10.  
  11. collation-server=utf8_general_ci 
  12.  
  13. default-storage-engine=INNODB  

表的字符集 

  1. show create table tasks; 
  2.  
  3. alter table tasks convert to character set utf8;   
責(zé)任編輯:龐桂玉 來(lái)源: w2n1ck
相關(guān)推薦

2016-09-23 13:34:15

PythonORMsqlalchemy

2015-04-14 09:38:35

軟件開(kāi)發(fā)人員便利工具

2015-07-07 09:26:08

SaaS亞馬遜云服務(wù)

2019-11-20 08:50:16

PythonORM工具包SQLAlchemy

2017-12-15 10:36:04

華為云

2019-07-11 15:24:30

開(kāi)發(fā)者技能工具

2012-02-20 09:55:54

虛擬化虛擬化技術(shù)虛擬服務(wù)器

2013-01-06 09:09:57

BYOD網(wǎng)絡(luò)設(shè)備

2023-05-18 07:58:27

2023-05-17 10:16:04

ORM工具包SQLAlchemy

2009-09-08 17:27:18

LINQ to Dat

2010-09-16 14:37:54

DataSetXML

2009-09-15 13:59:18

LINQ to Dat

2009-09-08 17:57:54

LINQ to Dat

2009-09-14 19:58:47

DataSet和Dat

2023-07-04 08:28:27

2016-05-12 13:48:05

DockerAPI

2025-02-19 07:59:06

2024-08-05 09:58:24

2009-08-12 15:43:02

操作C# Datase
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)