web2py 1.99.7中无法通过DAL连接MySQL数据库的问题

问题描述

根据在Ubuntu 10.04下配置MySQL数据库(完整版)一文的介绍,完成了MySQL数据库的配置,在客户端访问正常。

然后在web2py应用中通过DAL访问这个MySQL数据库时却碰到了问题:

Traceback (most recent call last): File “/home/www-data/web2py/gluon/restricted.py”, line 205, in restricted exec ccode in environment File “/home/www-data/web2py/applications/mianshi/models/db.py”, line 11, in db = DAL(‘mysql://chinakr:temp_pwd@localhost:3366/saedb’) File “/home/www-data/web2py/gluon/dal.py”, line 5968, in init raise RuntimeError, “Failure to connect, tried %d times:\n%s” % (attempts, tb) RuntimeError: Failure to connect, tried 5 times: Traceback (most recent call last): File “/home/www-data/web2py/gluon/dal.py”, line 5955, in init self._adapter = ADAPTERSself._dbname File “/home/www-data/web2py/gluon/dal.py”, line 1886, in initself.pool_connection(connect) File “/home/www-data/web2py/gluon/dal.py”, line 465, in pool_connection self.connection = f() File “/home/www-data/web2py/gluon/dal.py”, line 1885, in connect return self.driver.connect(**driver_args) File “/home/www-data/web2py/gluon/contrib/pymysql/init.py”, line 93, in Connect return Connection(*args, **kwargs) File “/home/www-data/web2py/gluon/contrib/pymysql/connections.py”, line 513, ininit self._connect() File “/home/www-data/web2py/gluon/contrib/pymysql/connections.py”, line 669, in _connect raise OperationalError(2003, “Can’t connect to MySQL server on %r (%d)” % (self.host, e.args[0])) OperationalError: (2003, “Can’t connect to MySQL server on ‘localhost’ (111)”)

也就是在web2py中通过DAL连接MySQL数据库失败。

问题分析

直接Google错误提示没有发现相关资料。

跟踪报错的web2py源代码:

$ vim /home/www-data/web2py/gluon/contrib/pymysql/connetctions.py 

第668和669行:

 except socket.error, e: raise OperationalError(2003, "Can't connect to MySQL server on %r (%d)" % (self.host, e.args[0])) 

也就是说,这个数据库无法连接的错误实际上是MySQL的Socket错误引起的。

解决问题

第一次尝试失败

在MySQL数据库服务器上:

$ sudo vim /etc/mysql/my.cnf [mysqld] socket = /tmp/mysql.sock 

重启MySQL服务器:

$ sudo service mysql restart 

注:根据后文叙述,这一步应该不是必须的。

问题终于解决了

根据Can’t connect to MySQL server on ‘localhost’中Kevin Ivarsen的描述:

MySQL can communicate over either TCP or a named pipe. It’s possible that your MySQL server is only listening on the named pipe. I could imagine that the mysql command line client would connect successfully over this channel, but Python would try to connect to the TCP socket and fail.

Try telnetting to the local mysql port and see what happens:

telnet localhost 3306

If you get an error like “connection refused”, then this is almost certainly the problem. Take a look at your mysql config file (/etc/mysql/my.cnf or similar) and look for the bind-address or skip-networking settings.

修改MySQL的端口绑定:

$ sudo vim /etc/mysql/my.cnf 

有两种修改方式:

  1. 只允许本地访问

“`

[mysqld] bind-address = 127.0.0.1 #bind-address = 211.147.217.171 

“`

  1. 允许本地和远程访问

“`

[mysqld] #bind-address = 127.0.0.1 #bind-address = 211.147.217.171 

“`

重启MySQL服务器:

$ sudo service mysql restart 

问题解决!

参考资料

在Python中控制中文标题长度的简单方法

Google关键字:python 中文 标题 长度

以web2py为例:

1. 问题

<li><span class=”right”>{{=article.pub_date}}</span>{{=article.title}}</li>

将输出:

海淀驾校新版网上约车系统12月1日起正式运行 2011-11-29

2. 解决方法

<li><span class=”right”>{{=article.pub_date}}</span>{{=article.title.decode(‘utf-8’)[0:18].encode(‘utf-8’)}}</li>

将输出:

海淀驾校新版网上约车系统12月1日起 2011-11-29

3. 原理

一个中文字符的长度等于两个ANSI字符的长度,因此,先把字符串转换为unicode,然后进行截取,再转换为UTF-8,这样就可以避免中英文字符长度不同计算麻烦或截取结果出现乱码(半个汉字)的情况。

web2py 1.99.3发布

流行的Python Web开发框架web2py发布了最新的1.99.3 stable版本。
web2py刚刚获得了InfoWorld颁发的Bossie Awards 2011大奖,评奖编辑给予web2py的评价是“The best open source application development software”。

下载地址:
官方下载

为将要发布的web2py 2.0做准备,这个版本中进行了主要修订。

具体的更新如下:

moved to GitHub and abandoned Lanchpad
new web site layout, thanks Anthony
new welcome app using skeleton, thanks Anthony
jQuery 1.7.1
modernizr 2.0.6 (customized)
define_table(‘thing’, singluar=’thing’,plural=’things’)
CAS 1.0 and 2.0 compliant, thanks Olivier
fixed validate_and_insert and validate_and_update, thanks Anthony
request.user_agent().is_mobile etc., thanks Ross and Angelo
better router, thanks Jonathan
app on/off buttons
support for dropbox_login
improved markmin recognizes qr code, supports auto audio/video/embed
response.optimize_css = ‘concat,minify,inline’, thanks Ross
response.optimize_js = ‘concat,minify,inline’ thanks Ross
db.define_table(…,common_filter=query), thanks Yair
db(…,ignore_common_filter=True)
support for stripe payments
support for DowCommerce payments, thanks Dave
experimental PyPy support
experimental mongodb support, thanks Mark
tickets in db now accessible from admin, thanks Niphlod
many grid improvements and bug fixes

和web2py 1.99.3同时发布的还有web2py Book第四版,这是学习web2py开发的主要书籍,官方出品,以eBook形式发售,在线版免费。

web2py中自动生成带关键字标题的方法

在Controller文件中:
response.title = ‘海淀驾校’
response.keywords = ‘北京海淀驾校, 海驾’

在Model文件中:
<title>{{if len((response.title + ‘ | ‘ + response.keywords).decode(‘utf-8’)) <= 80:}}{{=response.title}} | {{=response.keywords}}{{else:}}{{=response.title}}{{pass}}</title>

页面的标题是:
海淀驾校 | 北京海淀驾校, 海驾

注:
如果“标题 | 关键字”这种形式的标题超过了80个字符,那么将会采用“标题”这种形式,以符合SEO规范。

实例:
海淀驾校

在web2py中新建的controller无法访问怎么办

在web2py的admin后台新建了一个controller,名字是center,
在前台访问/center/时,提示:
invalid function (default/center)
也即center这个新建的contoller无法访问。

如果你的Web服务器采用的是nginx + uwsgi的解决方案,
那么你需要重启uwsgi服务。

在Ubuntu 10.04下可以使用下列命令:

$ sudo /etc/init.d/uwsgi-python restart

web2py中使用IS_IN_SET不当引起的数据不加载问题

Google关键字:list:string IS_IN_SET form.custom

问题:

Models的db.py中的定义:
Field(‘method’, ‘list:string’, default=’现金’),

db.applications.method.requires = IS_IN_SET((‘现金’, ‘刷卡’, ‘支票’, ‘在线支付’))

View的edit.py中的定义:
{{=form.custom.begin}}
{{=TR(T(‘Registered’) + ‘:’, form.custom.widget.registered)}}
{{=TR(”, form.custom.submit)}}
{{=form.custom.end}}

在生成的表单中,method字段虽然在数据库中保存有值,但在表单中并不加载。

解决方法:

根据网贴
list:string – IS_IN_SET
http://groups.google.com/group/fameisfame/browse_thread/thread/daec8390aa34d4ae/87e1df61f271ed71?lnk=raot
的提示,把代码修改为
db.applications.method.requires = IS_IN_SET((‘现金’, ‘刷卡’, ‘支票’, ‘在线支付’), multiple=True)
即可解决问题。

web2py中datetime本地化引起的验证错误

Google关键字:web2py view datetime localization validate, web2py form.custom localization datetime

问题描述:

db.py中的设置:
Field(‘registered’, ‘datetime’, default=request.now),

new.html中的设置:

{{=form.custom.begin}}
{{=TR(T(‘Registered’) + ‘:’, form.custom.widget.registered)}}
{{=TR(”, form.custom.submit)}}
{{=form.custom.end}}

在生成的表单中,默认值为:
2011-07-21 23:29:22
单击输入框会弹出一个日历,选择后会变成:
2011年7月21日 23时29分22秒

这是提交表达会出现验证错误(validation error),只有手工改回:
2011-07-21 23:29:22
才能提交成功。

解决办法:

原则上这应该是web2py的一个Bug,validation功能的本地化做得不完善。
可以通过修改Languages文件绕过这个Bug,也就是在zh-cn.py中,把
%Y-%m-%d
对应的值由
%Y年%m月%d日
改为%Y-%m-%d,
并把
%Y-%m-%d %H:%M:%S
对应的值由
%Y年%m月%d日 %H时%M分%S秒
改为
%Y-%m-%d %H:%M:%S。

这样在使用datepicker(日历)时,生成的日期时间总是
2011-07-21 23:29:22
这样的格式,也就不会再出现验证错误了。

web2py 1.97.1发布

web2py最新版本1.97.1已于本月26日发布,主要更新如下:
* 修复了大量小Bug

web2py 1.97.1下载:
* Windows版下载: http://www.web2py.com/examples/static/web2py_win.zip* 源代码下载: http://www.web2py.com/examples/static/web2py_src.zip

运行方式:1. Windows版直接运行web2py.exe;2. 源代码运行python web2py.py,需要有Python 2.5以上环境。

web2py使用说明: http://web2py.com/book