快来申请dbank网盘
上代码tw_ora_pool.py
#! /usr/bin/env python
#coding=cp936
from twisted.internet import reactor
from twisted.python import log
from twisted.enterprise import adbapi
from twisted.python.threadpool import ThreadSafeList
class Ora_pool(object):
'''
do_obj :
1 Template obj sql_t sql语句的模板
2 sql_t的参数列表para_list 是dict的list
'''
def __init__(self, user=None, passwd=None, tns=None, do_obj=None, cp=4):
self.do_obj = do_obj
self.dbpool = adbapi.ConnectionPool("cx_Oracle", user, passwd,\
tns, cp_min=cp, cp_max=cp)
self.result_list =ThreadSafeList()
self.err_list = ThreadSafeList()
def errback(self, e):
self.err_list.append(e)
if (len(self.result_list)+len(self.err_list))==\
len(self.do_obj.para_list):
self.dbpool.close()
reactor.stop()
def run(self):
if len(self.do_obj.para_list)==0:
return
try:
for para_dict in self.do_obj.para_list:
d = self.dbpool.runInteraction(self.do_sql, **para_dict)
d.addCallback(self.do_result)
d.addErrback(self.errback)
except:
log.msg("***gen paras failed!")
raise
reactor.run()
def do_sql(self, trans, **kwags):
try:
trans.execute(self.do_obj.sql_t.substitute(**kwags))
except Exception, e:
print Exception, e
log.msg("***ERROR***:%s" %(kwags))
raise
return kwags
def do_result(self, rs):
log.msg("***DONE***:%s" %(rs))
self.result_list.append(rs)
if (len(self.result_list)+len(self.err_list))==\
len(self.do_obj.para_list):
self.dbpool.close()
reactor.stop()
用法test_ora_pool.py
在linux 下很稳定,hp-unix 相对稳定 ,在win7下很不稳定
我的环境
Linux version 2.6.18-128.el5xen (mockbuild@hs20-bc1-5.build.redhat.com) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-44))
python2.6.5
cx_Oracle5.03
twisted 10.0.0
#! /usr/bin/env python
#coding=cp936
import sys
from string import Template
from twisted.python import log
from tw_ora_pool import Ora_pool
class my_sql(object):
pass
if __name__ == '__main__':
logfile = sys.stdout
log.startLogging(logfile)
test = my_sql()
test.sql_t = Template('''select count(*) from dual a
where ${id}=${id}''')
test.para_list = [dict(id=i) for i in range(0, 10)]
dp = Ora_pool(user='xxx', passwd='yyyy', tns='ttt',\
do_obj=test, cp=4)
dp.run()
dotlcoud的网站的部署步骤写的很简单,还是英文的,我英文也不好,我看的也不仔细,摸索着部署成功了,还是总结一下写出来,希望对使用 dotcloud平台的同学有帮助
sudo easy_install dotclouddotcloud deploy -h部署flask或者python应用,newblog.www是一个名字空间,不要和别人的重就可以 dotcloud deploy --type python newblog.www看一下是否创建成功dotcloud list如果使用数据库,再创建一个数据库的服务dotcloud deploy --type mysql newblog.dbdotcloud info newblog.db 可以得到root密码用dotcloud run newblog.db -- mysql -uroot -p,粘贴上一步看到的密码,登录进mysql数据库,创建你的数据库、用户,没有用ORM的话,手工建表,如果用了ORM,用ORM建表用ssh登录到dotcloud主机,dotcloud ssh newblog.www,需要API-key,你要登录进dotcloud网站,https://www.dotcloud.com/account/settings,可以看到,ssh登录的时候粘贴进去就可以了进入你本地的项目目录,上传代码dotcloud push ramen.www .ssh登陆到dotcloud主机,home目录下的code就是你上传的代码,在code目录编辑wsgi.py,修改一下你的配置文件,主要是静态文件static的目录,另一个如果用数据库,修改配置文件的连书库的用户、密码、主机等,用第6步的命令查看#!/usr/bin/env python
import sys
sys.path.append('/home/dotcloud/code')
from pypress import create_app
def application(environ, start_response):
app = create_app('config.cfg')
return app(environ, start_response)
dotcloud logs ramen.www 可以看你网站的日志,刚开始部署的时候免不了要调试,这个可以定位报错的代码flashback table tablename to before drop;
这个语句有时候可是救命的,能不能恢复,看你发现是否够早,回滚段是否够大
select * from tablename as of timestamp sysdate -1/24
这个是恢复到1小时之前的数据,误删除数据的时候可以用
在dotcloud上更新代码是到你的项目目录执行 "dotcloud push newblog.www ."
#! /usr/bin/env python
#coding=utf-8
from PIL import Image, ImageDraw, ImageFont
#from math import atan, degrees
import sys
import os,re
def get_jpg_time(filename):
time_pos = 0x12a
time_size = 19
f = open(filename)
f.seek(time_pos)
day = f.read(time_size)
f.close()
return day
#FONT = "/usr/X11R6/lib/X11/fonts/TTF/Vera.ttf"
FONT = r"C:\WINDOWS\Fonts\STXINGKA.TTF"
#FONT = r"C:\WINDOWS\Fonts\Vrinda.ttf"
def im_mark(filename, outfilename,cor_fill='rgb(0,255,0)',im_size=80):
#text = re.compile(':').sub('-',get_jpg_time(filename)[:11])
text = get_jpg_time(filename)
text = re.compile(':').sub('-',text[:11])+ ' '+text[11:16]
print text
img = Image.open(filename).convert("RGB")
watermark = Image.new("RGBA", (img.size[0], img.size[1]))
draw = ImageDraw.ImageDraw(watermark, "RGBA")
size = im_size
#size =184
font = ImageFont.truetype(FONT,size)
nexttextwidth, nexttextheight = font.getsize(text)
textwidth, textheight = nexttextwidth, nexttextheight
draw.setfont(font)
draw.text(((watermark.size[0]-textwidth-100),
(watermark.size[1]-textheight-100)), text,fill=cor_fill)
img.paste(watermark, None, watermark)
img.save(outfilename)
if __name__ == "__main__":
try:
ori_dir = sys.argv[1]
dest_dir = sys.argv[2]
except IndexError:
print "usage: jpg_mark.py photo_dir new_dir "
sys.exit(0)
if not os.path.isdir(dest_dir) :
os.mkdir(dest_dir)
name_reg = re.compile('jpg$',re.I)
for im in os.listdir(ori_dir):
if name_reg.search(im):
im_mark(os.path.join(ori_dir,im),os.path.join(dest_dir,im))
要改一下flask-sqlalchemy这个扩展,这可太好了,dotcloud可以媲美VPS了
@app.after_request
def shutdown_session(response):
self.session.remove() #把remove改成close就好了
return response
1 HP-UX B.11.31 U ia64 可选,未验证
添加openssl库的路径
openssl /opt/openssl/lib/hpux32
2 python 2.4.6 支持多线程
export BASECFLAGS=' -mt'
./configure --prefix=/jfdata/jfapp/wy/python24 --without-gcc --with-libs='-lcl -lpthread'
3 cx_Oracle 5.0.3
修改 libs = ["clntsh","ttsh10"]
编译python时有--with-libs='-lcl -lpthread' 不需要export LD_PRELOAD=/usr/lib/libcl.2
4 不用tns的连接方法
cn = cx_Oracle.connect('user','pass','192.168.1.1:1521/testdb1')
mysql> show processlist;
+------+------+------------------------------------+------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+------+------+------------------------------------+------+---------+------+-------+------------------+
| 1513 | app | ip-10-118-51-80.ec2.internal:45992 | blog | Sleep | 68 | | NULL |
| 1514 | app | ip-10-118-51-80.ec2.internal:45995 | blog | Sleep | 68 | | NULL |
| 1515 | app | ip-10-118-51-80.ec2.internal:46005 | blog | Sleep | 67 | | NULL |
| 1516 | app | ip-10-118-51-80.ec2.internal:46010 | blog | Sleep | 66 | | NULL |
| 1517 | app | ip-10-118-51-80.ec2.internal:46020 | blog | Sleep | 64 | | NULL |
| 1518 | app | ip-10-118-51-80.ec2.internal:46022 | blog | Sleep | 64 | | NULL |
| 1519 | app | ip-10-118-51-80.ec2.internal:46031 | blog | Sleep | 62 | | NULL |
| 1520 | app | ip-10-118-51-80.ec2.internal:46036 | blog | Sleep | 61 | | NULL |
| 1521 | app | ip-10-118-51-80.ec2.internal:46039 | blog | Sleep | 60 | | NULL |
| 1522 | app | ip-10-118-51-80.ec2.internal:46041 | blog | Sleep | 59 | | NULL |
| 1523 | app | ip-10-118-51-80.ec2.internal:46107 | blog | Sleep | 45 | | NULL |
| 1524 | app | ip-10-118-51-80.ec2.internal:46123 | blog | Sleep | 43 | | NULL |
| 1525 | app | ip-10-118-51-80.ec2.internal:46148 | blog | Sleep | 36 | | NULL |
| 1526 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+------+------+------------------------------------+------+---------+------+-------+------------------+
每刷一次页面,就会产生一个连接,随便点几个页面,就出来这么多连接,不释放,都是sleep的,我设置了这个参数set global wait_timeout=100 ;这个只能临时解决一下,没改这个参数之前,连接数到了最大值,网站就访问不了,刚发布那天动不动就是404,这个问题如何解决,到现在我还没找到彻底解决的办法...
在本机测试的时候,没有这个问题,怎么点页面就一个连接,昨天晚上试着换了postgresql,也是一样的连接不释放,这样看来和数据库应该没有关系,和sqlalchemy也没有关系,我怀疑是不是dotcloud平台连数据库时可能是经过端口转发,断开连接的时候就有问题
我的pypress博客发布有两天了,第一天一直在解决一些发布中的问题,第二天好不容易把问题都解决的差不多了,却发现dotcloud不太稳定,dotcloud的web服务器用的是nginx+uwsgi,老出现404的错误,把uwgi重启一下,或者直接ssh上去杀掉uwsgi的进程,就好了,我们公司上班的时间不能使用ssh,只有到下班时间才开放,上班时间几乎都访问不了,被打击了一下,再观察几天,还不稳定的话,有必要写一个监控了,发现404错误,就重启下uwsgi。
今天观察了一下,是mysql 连接不释放的问题,刷新一次页面在mysql 里show processlist 就发现多一个session,一直不释放,杀掉uwsg进程后,这些连接都消失了。这个如何解决..... 本机测试没这个问题,就1个连接
基于Flask的博客pypress在dotcloud上发布成功
在dotcloud上创建应用的步骤参考官方的文档就可以了,使用pypress几个需要注意的地方:
1 上传代码后,ssh连接到服务器,"dotcloud ssh yourservice",在$HOME/current 编辑wsgi.py,注意路径
#!/usr/bin/env python
import sys
sys.path.append('/home/dotcloud/code')
from pypress import create_app
def application(environ, start_response):
app = create_app('config.cfg')
return app(environ, start_response)
2 中文的问题
数据库我使用的是mysql,开始我sqlalchemy连接数据库指定了字符集"?character=utf8",写完博客保存,再查看都是乱码,google之后也解决了,问题出在dotcloud的mysql数据库默认字符集是latin1,sqlalchemy连接的时候不要加参数"?character=utf8",
SQLALCHEMY_DATABASE_URI = "mysql+mysqldb://user:password@ip:port/blog",就可以了
3 配置文件config.cfg要修改的地方,或者拷贝一份,在wsgi.py用新的名字也可以
SQLALCHEMY_DATABASE_URI ,用dotcloud info XXX.db 看你使用的数据库信息
UPLOADS_DEFAULT_DEST 上传图片的路径,ssh上去看一下就知道了
SECRET_KEY 这个也是必须修改的
其他根据需要修改吧
4 上传图片除了UPLOADS_DEFAULT_DEST 要设置对,pypress 一个小bug,不改也不能上传图片,这个本地修改就可以,很简单 frontend.py 在import os 后面加上 import json,上传就没问题了。
补充一下,dotcloud的静态文件是由nginx里服务的,static目录要在你current目录,建个符号链接就可以
ln -s pypress/static static
5 dotcloud有个很奇怪的地方,就是你程序如果出错了,整个网站就挂了,要重启一下服务才行
dotcloud restart newblog.www
dotcloud能用ssh, 感觉自由度比较大,可以随便的安装python包,而且速度超快,从国内访问速度不快,毕竟是免费的,可以接受。