MySQL sql_safe_updates


遇到一个问题

DELETE FROM 表名字 WHERE 条件; 报错:


Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
 To disable safe mode, toggle the option in Preferences -> SQL Queries and reconnect.4

官网上面这么说

https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_sql_safe_updates

If set to 1, MySQL aborts UPDATE or DELETE statements that do not use a key in the WHERE clause or a LIMIT clause. (Specifically, UPDATE statements must have a WHERE clause that uses a key or a LIMIT clause, or both. DELETE statements must have both.) This makes it possible to catch UPDATE or DELETE statements where keys are not used properly and that would probably change or delete a large number of rows. The default value is 0.

sql_safe_updates = 1 时开启sql_safe_updates,update和delete在修改数据时,如果不带limit,需要where条件可以走索引,否则会报错

所以要 sql_safe_updates =0

如果想要设置默认值可以修改 my.cnf 配置文件

SET SQL_SAFE_UPDATES=0;

或者

SET SQL_SAFE_UPDATES=1;

重启 MySQL 服务


《熔炉》

取材2005年光州一所聋哑障碍人学校的真实事件,改编自韩国作家孔枝泳的同名小说


7aec54e736d12f2eebfcab9f4fc2d56284356857.jpg 两个小时的电影,场面压抑,冰冷的现实让人窒息,

电影悲剧的结局更是引人深思 。 全局贯穿并没有提到熔炉两个字

“ 雾津 ”一个充满了寓意的地名, “玻璃” 尤其是最后主人公抱着的民秀遗像被 踩碎的场景,实为震撼。

结尾的几句话打动了我

有一次,在吃饭的时候我问过妍斗 和侑利,这件事发生之前和发生之后,最大的变化是什么

孩子们如是说:我们明白了 我们也和其他人一样,有人来珍惜 。

我们一路奋战,不是为了改变世界,而是为了不让世界改变我们 。天气变冷了,冬天冷,是因为为了让我们懂得,周围人的温暖 是多么的珍贵


Python 装饰器

不只是在 Java C++ 中有面向对象的说法 在 Python中 也经常被 这么说 一切皆对象 在OOP ( 面向对象 )的设计模式中,decorator 被称为装饰模式。其中这种装饰模式需要通过继承和组合来实现,而Python 则直接从语法层次支持 decorator 。


从 Python 2.4版本开始 提供了装饰器(decorator) 装饰器本质上就是一个函数,这个函数接收其他函数作为参数,(有点类似于回调函数 callback)并将其以一个新的修改后的函数进行替换。

装饰器本身可以使用多次,也可以同时使用多个装饰器  


装饰器定义 & 使用

 

函数嵌套就是定义一个外部函数,里面又定义了一个内部的函数,结果返回这个内部函数

而装饰器就是这个外部函数 传进来一个参数(这个参数可以是一个函数),内部函数里面调用这个参数(函数)然后返回这个内部的函数。

 

使用一个装饰器就是 : @ 装饰器的名字, 如果装饰器有参数,里面可以加上装饰器的参数 ,换一种说法:装饰器可以理解为 一个语法糖( 语言自身提供,用更加简便的方式表示某种行为 ), 就是将被装饰的函数作为参数 传递给装饰器函数

 


In [1]: import time 

In [2]: def wait_five_seconds(f):   # 接收一个函数作为参数
   ...:     # 修改这个参数 
   ...:     def wrapper():
   ...:         print "Begin--------"
   ...:         print "Please wait five seconds"
   ...:         time.sleep(5)
   ...:         f()     # 中间也可能调用这个函数
   ...:         print "Finish--------"
   ...:     return wrapper     # 然后return一个修改后的新的函数,也就是替换后的函数
   ...: 

# 调用装饰器

In [3]: @wait_five_seconds   
   ...: def say_hello(name="Word"):
   ...:     print "Hello {}".format(name)
   ...:     

In [4]: say_hello()
Begin--------
Please wait five seconds
Hello Word
Finish--------

# def say_hello(name="Word"):
# 	print "Hello {}".format(name)
# say_hello_wait = wait_five_seconds(say_hello)
# say_hello_wait

 

语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。

例如 :简单来说, for、while 循环就是语法糖,就是一种很便捷写法,它的存在可以增加语言的可读性,简化一些操作。

 

使用洽到好处的装饰器 瞬间就可以让 你的代码优美很多,适当使用装饰器,(注意 适当使用,使用太多,代码反而可读性变差 )能够有效的提高代码的可读性以及 可维护性


什么时候会用到装饰器 & 装饰器应该怎么用

使用场景

预处理 就是我在调用函数的时间进行参数的检查,后处理 就不用提了

得到函数的名字和函数的参数,就可以把调用的过程打印到日志里面,这样我们就知道什么时候调用过这个函数,以及调用过程中的函数参数是什么,这样的过程

f.__name__ 得到函数名

*args 位置参数 **kwargs 关键字参数

 


def logging(func):
	def wrapper(*args, **kwargs):
		res = func(*args, **kwargs)
		print func.__name__,args,kwargs    # 打印函数名和参数 可以用logging 打印到日志文件里面
		return res
	return wrapper
	
@logging
def reverse_string(string):
    return str(reversed(string))

 

就是调用之前记录一下开始时间,函数结束之后调用一下时间,然后返回时间差,就可以知道函数执行了多少时间 如下例子:


import time 

def benchmark(func):
	def wrapper(*args, **kwargs):
		t = time.clock()    # 调用钱记录开始时间
		res = func(*args, **kwargs)
		print func.__name__    #打印日志
		print time.clock() - t    # 计算用了多长时间
		return res
	return wrapper

@benchmark
def reverse_string(string):
	return str(reversed(string))

 

注意事项


In [7]: import time 
# In [25]: import functools

In [8]: def say_hello(f):
   ...:     # @functools.wraps(f)
   ...:     def wait_five_seconds(*args, **kwargs):
   ...:         print ''' "Begin--------"
   ...: "Please wait five seconds" '''
   ...:         time.sleep(5)
   ...:         f()
   ...:         print "Finish--------"
   ...:     return wait_five_seconds    
   ...: 

In [9]: @say_hello   
   ...: def hello(name="Lmy"):
   ...:     """ Say Hello to Lmy """
   ...:     print "Hello {}".format(name)
   ...:     

In [10]: 

In [10]: hello()
Begin--------
Please wait five seconds
Hello Lmy
Finish--------

In [11]: print hello.func_doc 
None

In [12]: print hello.func_name
wait_five_seconds

# In [29]: print hello.func_doc 
#  Say Hello to Lmy 
# 
# In [30]: print hello.func_name
# hello

 

为了给装饰器传递参数可以在 函数的外围再套一个函数,传递参数也就是说一层一层的返回 调用装饰器的时候加上所需要的参数 就比如说 Flask 的 route() 装饰器,告诉 Flask 什么样的 URL 能触发函数。


from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello():
    return 'Hello World'
    
@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % username

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

if __name__ == "__main__":
    app.run()

此例中,使用 app.route 装饰器,完成了以下几个 URL 与处理函数的 route:

{ 
    '/': index(), 
    '/hello': hello(),
    '/user/<username>': show_user_profile(username)
    '/post/<int:post_id>' : show_post(post_id)
}

也就是 当 HTTP 请求的 URL 为 xxxx 时,Flask 会调用 某一个 函数;


缺点:


参考资料

  1. https://wiki.python.org/moin/PythonDecoratorLibrary


Python - Flask 实现登录功能(一)

登录功能 Python Flask 框架 实现登录模块 引用 bootstrap 支持 实现登录页面如下:


http://olinvkfrw.bkt.clouddn.com/3161463909.png

实现过程

登录

登录提示输入 username 和 password 如果相符则 return Hello word

如果用户名不符则返回

error'Invalid username'

否则密码不符则返回

'Invalid password'

否则返回已经登录,并且返回 Hello word

session['logged_in'] = True
flash('You were logged in')
return "Hello word"

更改

登录

登录提示输入 username 和 password 如果相符则 return Hello word

如果用户名不符则返回

error'Invalid username'

Image.png

否则密码不符则返回

'Invalid password'

Image.png

否则返回已经登录,并且返回跳转页面到 /

session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('hello_world'))

Image.png

登出

session.pop('logged_in', None)
    flash('You were logged out')
    return render_template('logout.html')

Image.png


login.py

# -*- coding: UTF-8 -*-

from flask import (Flask, render_template, g, session, redirect,                            url_for,request, flash)
from flask_bootstrap import Bootstrap

DEBUG = True
SECRET_KEY = 'key'

app = Flask(__name__)

bootstrap = Bootstrap(app)

app.secret_key = SECRET_KEY
app.config.from_object(__name__)
app.config['USERNAME'] = 'admin'
app.config['PASSWORD'] = 'admin'


@app.route('/login')
def hello_world():
    return render_template('hello.html')


@app.route('/', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != app.config['USERNAME']:
            error = 'Invalid username'
        elif request.form['password'] != app.config['PASSWORD']:
            error = 'Invalid password'
        else:
            session['logged_in'] = True
            flash('You were logged in')
            return redirect(url_for('hello_world'))
    return render_template('login.html', error=error)


@app.route('/logout')
def logout():
    session.pop('logged_in', None)
    flash('You were logged out')
    return render_template('logout.html')


if __name__ == '__main__':
    app.run(host="127.0.0.1")


templates 文件夹下 的HTML代码我就不粘贴了,大部分都是基于jinjia2模板引擎渲染

放在 GitHub 中有兴趣的可以查看

templates


另外解决了一个 typecho 上传图片失败的问题

首先更改 usr/uploads 777 权限并没有解决,后来自行狗哥一番用另一种方法解决了

xxxxxxxxxxxx/var/Typecho/Common.php 800多行左右

public static function isAppEngine()
    {
        return !empty($_SERVER['HTTP_APPNAME'])                     // SAE
            || !!getenv('HTTP_BAE_ENV_APPID')                       // BAE
            || !!getenv('SERVER_SOFTWARE')                          // BAE 3.0
            || (ini_get('acl.app_id') && class_exists('Alibaba'))   // ACE
            || (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'],'Google App Engine') !== false) // GAE;
    }

!!getenv('SERVER_SOFTWARE') 替换为 !!getenv('HTTP_BAE_LOGID')


实现的比较无脑,页面也丑陋不堪,功能更是shi到不能再shi,连Remember me 的功能也没实现,但是本人正在学习进步中,下一次会来好好改进一番

个人觉得这个功能页面很是有问题,如果大家看出问题可以随时与我联系,希望大家多多指教。



Python与MySQL数据类型及数据处理(二)

综合 MySQL 数据类型和 Python 数据类型 ,以及 MySQL 和 Python 这两种有代表性的数据库和语言 分别对数据的操作 总结为一下内容,其中 对于之前的 MySQL 数据类型和 Python 数据类型 文章 做一个总结 顺便重点带一下 Python 的内置数据类型里面没有的 日期和时间 这个数据类型


数字

MySQL中 数字类型有两种

整形:int,tinyint,smallint,bigint ,medium

浮点型: float,double,decimal

其中的一些问题我在之前的文章里面也有谈过

详情请见

http://mingyueli.com/cn/2017/02/11/python-mysql-data-type-and-deal-1/

但是 python 中 只有整数 int 和浮点数 float 的区别

python 的数字是无限扩展的(没有溢出的概念,也就是说可以无限大)在 python2 里面整数有 int 和 long ,但是 python3 里面已经统一了

# python3

Python 3.5.2 (default, Jul  5 2016, 12:43:10) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a=1
>>> a
1
>>> type(a)
<class 'int'>
>>> a=2.1
>>> type(a)
<class 'float'>
>>> a=11111111111111111111111111111111111111111111
>>> type(a)
<class 'int'>
>>> 
# python2

Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=11111111111111111111111
>>> type(a)
<type 'long'>
>>> a=1
>>> type(a)
<type 'int'>
>>> 


字符串类型

在 MySQL 里字符串有很多类型:

char,vachar,text,tinytext,mediumtext,longtext,binary,varbinary,blob,tinyblob ,mediumblob,longblog

每种类型占的字节大小存储的需求也有所不同不同

在python中所有字符串类型都是str(还可以通过下标来访问)

In [6]: a= "my"

In [7]: type (a)
Out[7]: str

时间类型:

MySQL里面时间类型分为五种 :date , datetime , time , year , timestamp(表示的格式有所不同,所占的字节大小也不同)

python的内置数据类型里面没有日期和时间这个数据类型,但是可以通过 datetime 和 ` time ` 标准库模块来实现对日期时间的管理,下面我们来重点说一下python 实现时间和日期的标准库。

可以转换为 时间数组,时间戳,自定义格式的时间类型  

下面就用python的标准库 time 将 字符串转换为时间戳或者指定的时间格式输出  

In [1]: a = "2017-02-13 10:10:00"

In [2]: import time
   ...:

In [3]: timeArray = time.strptime(a,"%Y-%m-%d %H:%M:%S")     #转换为数组

In [4]: timeArray
Out[4]: time.struct_time(tm_year=2017, tm_mon=2, tm_mday=13, tm_hour=10, tm_min=
10, tm_sec=0, tm_wday=0, tm_yday=44, tm_isdst=-1)

In [5]: timestamp = int(time.mktime(timeArray))     #把数组形式转换为时间戳

In [6]: timestamp
Out[6]: 1486951800

In [7]: timeStyle1 = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)     #把数组转换成指定的时间格式输出

In [8]: timeStyle1
Out[8]: '2017-02-13 10:10:00'

In [9]: timeStyle2 = time.strftime("%Y/%m/%d %H:%M:%S", timeArray)

In [10]: timeStyle2
Out[10]: '2017/02/13 10:10:00'

In [11]: timeStyle3 = time.strftime("%Y/%m/%d", timeArray)
    ...:

In [12]: timeStyle3
Out[12]: '2017/02/13'

In [13]: timeStyle4 = time.strftime(" %H:%M:%S", timeArray)

In [14]: timeStyle4
Out[14]: ' 10:10:00'

In [15]:

 

得到当前时间并且转换为指定的格式输出  

In [17]: now = int(time.time())     #当前时间输出为时间戳格式

In [18]: now
Out[18]: 1486952084

In [19]: timeArray = time.localtime(now)     #时间戳转换成数组形式

In [20]: timeArray
Out[20]: time.struct_time(tm_year=2017, tm_mon=2, tm_mday=13, tm_hour=10, tm_min
=14, tm_sec=44, tm_wday=0, tm_yday=44, tm_isdst=0)

In [21]: timeStyle5 = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)     # 由数组形式转换成指定时间格式输出

当前时间显示时间类型: time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) &nbsp

mysql 的日期函数

 

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2017-02-13 10:19:48 |
+---------------------+
1 row in set (0.00 sec)

mysql> select sysdate();
+---------------------+
| sysdate()           |
+---------------------+
| 2017-02-13 10:19:58 |
+---------------------+
1 row in set (0.00 sec)

mysql> select sysdate(),now(),sleep(5),now(),sysdate();
+---------------------+---------------------+----------+---------------------+--
-------------------+
| sysdate()           | now()               | sleep(5) | now()               | s
ysdate()           |
+---------------------+---------------------+----------+---------------------+--
-------------------+
| 2017-02-13 10:20:05 | 2017-02-13 10:20:05 |        0 | 2017-02-13 10:20:05 | 2
017-02-13 10:20:10 |
+---------------------+---------------------+----------+---------------------+--
-------------------+
1 row in set (5.00 sec)

mysql>


复合类型:

MySQL 还支持两种复合数据类型 ENUM 和 SET,它们扩展了 SQL 规范。虽然这两种类型在技术上是字符串类型,但是可以被视为不同的数据类型。

两者的区别就是 : 一个 ENUM 类型只允许从一个集合中取得一个值;而 SET 类型允许从一个集合中取得任意多个值。


如何看 python 处理数据和 mysql 处理数据

MySQL 用处主要是存储和查询数据,

Python 的用处主要是可以用来获取数据操作数据,比如说操作文件,可以从文件里面读出数据,对文件里面的数据进行处理,再比如说爬虫,从一堆网页中获取所需要的数据,分析数据和数据挖掘 ,比如说 pandas 可以将数据的格式转换成你想要的格式,比如说CSV 等等,进行一些数据的变换去更适合统计学或者是科学方面的研究。可以操作数据库,最后将想要的结果输出或者存储到数据库(支持关系型,非关系型)中。

简单来说 就是一个是数据的计算,一个是数据的存储



Pagination