ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>国产综合欧美,在线视频资源站,videoxxxx另类日本极品http://www.aygfsteel.com/sean/category/37361.htmlRead me, read Sean.zh-cnTue, 26 Jul 2011 21:12:20 GMTTue, 26 Jul 2011 21:12:20 GMT60pyPdf - 用Python方便的处ç†PDF文档http://www.aygfsteel.com/sean/archive/2011/07/26/355089.htmllaogaolaogaoTue, 26 Jul 2011 14:25:00 GMThttp://www.aygfsteel.com/sean/archive/2011/07/26/355089.htmlhttp://www.aygfsteel.com/sean/comments/355089.htmlhttp://www.aygfsteel.com/sean/archive/2011/07/26/355089.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/355089.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/355089.html 今天临时有个需求,那就是给æŸPDF文档切边åQŒä»¥æ–¹ä¾¿åœ¨Kindle 3çš?å‹å±ä¸Šé˜…诅R€?br />
很久没碰Python了,ä¸è¿‡æˆ‘相信用Python一定有办法解决˜q™ä¸ªéœ€æ±‚,于是¾l过½Ž€å•çš„googlingåQŒä¾¿å‘现了这个pyPdfåº?( http://pybrary.net/pyPdf/ ) åQŒæ“作è“væ¥ç›¸å½“直接易懂,把代ç è„“(chu¨¤ng)在这儿,åšä¸ªè®°å½•ã€?br />
 1 from pyPdf import PdfFileWriter, PdfFileReader
 2 
 3 pdf = PdfFileReader(file('original.pdf''rb'))
 4 out = PdfFileWriter()
 5 
 6 for page in pdf.pages:
 7   page.mediaBox.upperRight = (580,800)
 8   page.mediaBox.lowerLeft = (128,232)
 9   out.addPage(page)
10 
11 ous = file('target.pdf''wb')
12 out.write(ous)
13 ous.close()

Enjoy!


laogao 2011-07-26 22:25 å‘表评论
]]>
[Pylons] Mako™åµé¢æ¨¡æ¿å¼•擎http://www.aygfsteel.com/sean/archive/2009/01/27/252614.htmllaogaolaogaoTue, 27 Jan 2009 07:50:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/27/252614.htmlhttp://www.aygfsteel.com/sean/comments/252614.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/27/252614.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252614.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252614.htmlPylons是一个典型的MVC Web框架åQŒåœ¨ä¹‹å‰çš„几½‹‡éš½W”中åQŒæˆ‘们一起了解了Pylons的安装ã€é»˜è®¤é¡¹ç›®ç»“æž„ã€Routeså’Œcontroller("C")以åŠSQLAlchemy("M")åQŒåœ¨˜q™ä¸ª¾pÕdˆ—的最åŽï¼Œæˆ‘们一èµäh¥çœ‹çœ‹"V"ã€?br />
在我们的controller代ç ä¸­ï¼Œæ¯ä¸ªaction在return的时候,å¯ä»¥é€‰æ‹©åQ?br />1- 直接return字符ä¸?br />2- 通过render()函数ž®†è¾“å‡ÞZº¤¾l™é¡µé¢æ¨¡æ¿å¼•擎处ç?br />3- redirect_to()é‡å®šå‘到其他URL

直接return太简å•,redirect_to也没有特别需è¦ä»‹¾lçš„åQŒé‡ç‚¹çœ‹render()。如果你一直follow˜q™ä¸ª¾pÕdˆ—åQŒé‚£ä¹ˆåœ¨ä½ çš„controllers/hello.py中,å¯ä»¥çœ‹åˆ°˜q™æ ·ä¸€è¡ŒimportåQ?br />
from newapp.lib.base import BaseController, render

从lib.base引入了一个render函数åQŒè·Ÿåˆ°l(f¨¡)ib/base代ç é‡ŒæŸ¥çœ‹ï¼Œæˆ‘们会知é“:
from pylons.templating import render_mako as render
其实我们用到的render()函数åQŒæ˜¯pylons.templating.render_mako的别åã€?br />
æ³? ˜q™é‡Œå‡å®šä½ åœ¨paster createæ—‰™€‰æ‹©äº†é»˜è®¤çš„makoåQŒå…¶ä»–Pylons原生支æŒçš„页颿¨¡æ¿å¼•擎还有结构相å¯ÒŽ(gu¨©)›´å±‚次化的Genshi和更接近Django实现的Jinjaã€?br />
render_mako()函数½{‘Ö如下åQ?br />render_mako(template_name, extra_vars=None, cache_key=None, cache_type=None, cache_expire=None)

最基本的用法是¾l™å‡ºtemplateæ–‡äšgå,然åŽé€šè¿‡extra_vars传入傿•°åQŒPylons默认查找™åµé¢æ¨¡æ¿æ–‡äšg是在™å¹ç›®çš„templateså­ç›®å½•,˜q™ä¸ªè·¯å¾„也å¯ä»¥åœ¨config/environment.py中修æ”V€‚在Pylons中,被推è的传å‚åšæ³•是ä‹É用tmpl_contextåQŒåœ¨ç”Ÿæˆcontroller的时候,已ç»è‡ªåЍimport了tmpl_contextòq¶åˆ«å䨓cåQŒè¿™æ øP¼Œæˆ‘们åªéœ€è¦åœ¨c上绑上我们需è¦ä¼ é€’给模æ¿çš„æ•°æ®ï¼Œæ¨¡æ¿åœ¨è§£æžæ—¶åQŒä¹Ÿž®Þpƒ½å¤Ÿé€šè¿‡c得到˜q™äº›æ•°æ®äº†ã€‚僘q™æ ·åQ?br />
c.name = u'Pylons n00b'
return render('hello.mako')

ç„¶åŽåQŒåœ¨hello.mako中:
<h3>Hello <b>${c.name}</b>!</h3>

在模æ¿ä»£ç ä¸­åQŒæœ‰äº›Pylons¾pÈ»Ÿå˜é‡/函数是å¯ä»¥ç›´æŽ¥è®¿é—®çš„åQŒåŒ…括:
tmpl_context (c) - 用于controllerå’Œtemplate传递数æ?br />config - é…置信æ¯
app_globals (g) - 应用的全局å˜é‡
h - WebHelpersåQŒåŒ…括h.formã€h.link_toã€h.url_for½{‰ç­‰å®žç”¨å‡½æ•°
request - è¯äh±‚
response - 应答
session - 会è¯ä¿¡æ¯
translatorã€ungettext()ã€_()ã€N_() - 处ç†å›½é™…åŒ?br />
除了基本çš?{}å˜é‡æ›¿ä»£è¯­æ³•之外åQŒç±»ä¼¼JSPåQŒMako˜q˜æ”¯æŒæ³¨é‡Šã€if/else/for控制逻辑ã€ä»£ç ç‰‡ŒDüc€returnã€æ ‡½{„¡­‰åQŒå…·ä½“çš„å¯ä»¥æ‰«ä¸€çœ¼å®˜æ–¹è¯´æ˜Žï¼š
http://www.makotemplates.org/docs/syntax.html
很精½Ž€åQŒä¹Ÿéžå¸¸å®ÒŽ(gu¨©)˜“ç†è§£åQŒè¿™é‡Œå°±ä¸è¯¦¾l†è¯´æ˜Žäº†ã€?br />
è‡Ïx­¤åQŒæˆ‘们已¾l了解了Pylons最核心的几个组ä»Óž¼Œ­‘›_¤Ÿæˆ‘们æ­å¾å¸¸è§„çš„Web应用了。其他值得大家¾l§ç®‹æŒ–掘的内容包括:国际化ã€è¡¨å•验è¯?FormEncode)ã€ç”¨æˆ·éªŒè¯å’Œæƒé™(AuthKitã€repoze.whoã€repoze.what)ã€AJAXã€Python 3.0ã€WSGI基础架构½{‰ã€?br />
本文是该¾pÕdˆ—最åŽä¸€½‹‡ï¼Œå¸Œæœ›é€šè¿‡½Ž€å•的介ç»å’Œå­¦ä¹ ï¼Œå¤§å®¶èƒ½å¤Ÿå–œæ¬¢òq‰™¡ºåˆ©çš„上手PylonsåQŒä¹Ÿå¸Œæœ›­‘Šæ¥­‘Šå¤šçš„ähå…Ïx³¨˜q™ä¸ªä¼˜ç§€çš„Python Web应用框架ã€?br />


laogao 2009-01-27 15:50 å‘表评论
]]>
[Pylons] 在Pylons环境下ä‹É用SQLAlchemyhttp://www.aygfsteel.com/sean/archive/2009/01/27/252612.htmllaogaolaogaoTue, 27 Jan 2009 06:00:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/27/252612.htmlhttp://www.aygfsteel.com/sean/comments/252612.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/27/252612.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252612.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252612.html在å‰é¢çš„4½‹‡éš½W”中åQŒæˆ‘们简è¦çš„介ç»äº†SQLAlchemyåQŒä¸˜q‡SQLAlchemy如何被集æˆåˆ°Pylons应用中呢åQ?br />
首先我们看一下自动生æˆä»£ç ä¸­çš„modelå­ç›®å½•,其中有两个文件__init__.pyå’Œmeta.pyåQŒå…¶ä¸­meta.py定义了engineã€Sessionå’Œmetadata三个公用å˜é‡åQŒè€Œ__init__.pyæä¾›äº†ä¸€ä¸ªæ ¸å¿ƒçš„init_model(engine)æ–ÒŽ(gu¨©)³•åQŒè¯¥æ–ÒŽ(gu¨©)³•分别ž®†æ•°æ®åº“engine和绘q‡sessionmakerå’Œscoped_session包装的Session对象æ¤å…¥åˆ°meta中,åƒè¿™æ øP¼š
    sm = orm.sessionmaker(autoflush=True, autocommit=True, bind=engine)

    meta.engine 
= engine
    meta.Session 
= orm.scoped_session(sm)

˜q™æ ·ä¸€æ¥ï¼Œæ•´ä¸ªèƒŒåŽçš?magic"ž®Þp¿˜å‰©ä¸‹æœ€åŽä¸€å?拼图"åQšè°æ¥æŠŠengineåˆå§‹åŒ–好òq¶è°ƒç”¨init_modelæ–ÒŽ(gu¨©)³•呢?看看config/environment.pyž®±æ¸…楚了åQ?br />
 1 """Pylons environment configuration"""
 2 import os
 3 
 4 from mako.lookup import TemplateLookup
 5 from pylons.error import handle_mako_error
 6 from pylons import config
 7 from sqlalchemy import engine_from_config
 8 
 9 import newapp.lib.app_globals as app_globals
10 import newapp.lib.helpers
11 from newapp.config.routing import make_map
12 from newapp.model import init_model
13 
14 def load_environment(global_conf, app_conf):
15     """Configure the Pylons environment via the ``pylons.config``
16     object
17     """
18     # Pylons paths
19     root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
20     paths = dict(root=root,
21                  controllers=os.path.join(root, 'controllers'),
22                  static_files=os.path.join(root, 'public'),
23                  templates=[os.path.join(root, 'templates')])
24 
25     # Initialize config with the basic options
26     config.init_app(global_conf, app_conf, package='newapp', paths=paths)
27 
28     config['routes.map'] = make_map()
29     config['pylons.app_globals'] = app_globals.Globals()
30     config['pylons.h'] = newapp.lib.helpers
31 
32     # Create the Mako TemplateLookup, with the default auto-escaping
33     config['pylons.app_globals'].mako_lookup = TemplateLookup(
34         directories=paths['templates'],
35         error_handler=handle_mako_error,
36         module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
37         input_encoding='utf-8', output_encoding='utf-8',
38         imports=['from webhelpers.html import escape'],
39         default_filters=['escape'])
40     
41     # Setup SQLAlchemy database engine
42     engine = engine_from_config(config, 'sqlalchemy.')
43     init_model(engine)
44     
45     # CONFIGURATION OPTIONS HERE (note: all config options will override
46     # any Pylons config options)

注愽W?行的import和第42ã€?3行代ç ï¼Œæ˜¯ä¸æ˜¯è±ç„¶å¼€æœ—?Pylons在åˆå§‹åŒ–˜q行环境æ—Óž¼Œä»Žconfig中读å–sqlalchemy相关的酾|®ä¿¡æ¯ï¼Œç„¶åŽé€šè¿‡˜q™äº›é…置信æ¯åˆ›å¾æ•°æ®åº“engineåQŒåƈ调用init_model()æ–ÒŽ(gu¨©)³•åˆå§‹åŒ–SQLAlchemy功能的核心对象:metadataå’ŒSession。有了meta.SessionåQŒæˆ‘们就å¯ä»¥æ–¹ä¾¿çš„在代ç ä¸­æ‰§è¡Œå¯¹modelå±?æ•°æ®åº“的讉K—®äº†ã€?br />


laogao 2009-01-27 14:00 å‘表评论
]]>
[Pylons] SQLAlchemyèµäh­¥ - IV. Object Relational Mapperhttp://www.aygfsteel.com/sean/archive/2009/01/27/252609.htmllaogaolaogaoTue, 27 Jan 2009 04:52:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/27/252609.htmlhttp://www.aygfsteel.com/sean/comments/252609.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/27/252609.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252609.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252609.html接ç€å‰é¢çš„例å­è¯´åQŒæˆ‘们定义了book_tableå’Œauthor_tableåQŒæŽ¥ä¸‹æ¥åQ?br />
 1 class Book(object):
 2     def __init__(self, title):
 3         self.title = title
 4     def __repr__(self):
 5         return "<Book('%s')>" % self.title
 6 
 7 class Author(object):
 8     def __init__(self, name):
 9         self.name = name
10     def __repr__(self):
11         return "<Author('%s')>" % self.name

˜q™é‡Œæˆ‘们定义两个¾c»ï¼Œ¾l§æ‰¿è‡ªobjectåQŒç±»ä¼¼JavaBeans或者POJOåQŒè¿™é‡Œçš„__init__æ–ÒŽ(gu¨©)³•å’Œ__repr__æ–ÒŽ(gu¨©)³•䏿˜¯å¿…é¡»çš„ï¼Œåªæ˜¯ä¸ÞZº†åˆ›å¾å¯¹è±¡å’Œè¾“出对象内å®ÒŽ(gu¨©)¯”较方ä¾Ñ€‚ç„¶åŽå°±å¯ä»¥ç”¨SQLAlchemyçš„mapperå’Œsessionmakeræ¥å¾ç«‹æ˜ ž®„å…³¾pÕdÆˆå¤„ç†æŒä¹…和查询等æ“作åQ?br />
 1 from sqlalchemy.orm import mapper,sessionmaker
 2 
 3 mapper(Book, book_table)
 4 mapper(Author, author_table)
 5 
 6 Session = sessionmaker(bind=engine)
 7 session = Session()
 8 
 9 gia = Book(u'Groovy in Action')
10 ag = Author(u'Andrew Glover')
11 
12 session.add(gia)
13 session.add(ag)
14 session.add_all([Book('Hibernate in Action'), Author('Gavin King')])
15 s_gia = session.query(Book).filter_by(title=u'Groovy in Action').first()
16 s_gia.title =u'Groovy in Action Updated'
17 
18 print "[DIRTY]", session.dirty
19
20 session.commit() # or session.rollback()

如果你用˜q‡HibernateåQŒé‚£ä¹ˆè¿™äº›ä»£ç å¯¹ä½ æ¥è¯ß_¼Œç†è§£èµäh¥åº”该没有ä»ÖM½•隑ֺ¦ã€?br />
å‡å¦‚我告诉你åQŒæ¯‹Æ¡éƒ½è¦åƒ˜q™æ ·å…ˆå®šä¹‰Table(schema)åQŒå†å®šä¹‰classåQŒç„¶åŽç”¨mapper建立对照åQŒæ˜¯ä¸æ˜¯æœ‰ç‚¹é‚£å•¥åQŸSQLAlchemy的开å‘者们也æ„识到˜q™ä¸€ç‚¹ï¼Œæ‰€ä»¥ä»Ž0.5开始,SQLAlchemyå¯ä»¥é€šè¿‡sqlalchemy.ext.declarativeæ”¯æŒæˆ‘们实现更紧凑的model/schema定义åQ?br />
 1 from sqlalchemy.schema import Table, Column, ForeignKey, Sequence
 2 from sqlalchemy.types import *
 3 from sqlalchemy.orm import relation
 4 from sqlalchemy.ext.declarative import declarative_base
 5 
 6 Base = declarative_base()
 7 metadata = Base.metadata
 8 
 9 bookauthor_table = Table('bookauthor', metadata,
10     Column('book_id', Integer, ForeignKey('book.id'), nullable=False),
11     Column('author_id', Integer, ForeignKey('author.id'), nullable=False),
12 )
13 
14 class Book(Base):
15     __tablename__ = 'book'
16     id = Column(Integer, Sequence('seq_pk'), primary_key=True)
17     title = Column(Unicode(255), nullable=False)
18     authors = relation('Author', secondary=bookauthor_table)
19 
20 
21 class Author(Base):
22     __tablename__ = 'author'
23     id = Column(Integer, Sequence('seq_pk'), primary_key=True)
24     name = Column(Unicode(255), nullable=False)
25     books = relation('Book', secondary=bookauthor_table)

˜q™é‡Œæˆ‘们用到了many-to-many关系åQŒå…¶ä»–的常è§ç”¨æ³•˜q˜åŒ…括many-to-oneã€one-to-manyã€JOINã€å­æŸ¥è¯¢ã€EXISTSã€Lazy/Eager Loadã€Cascade (all/delete/delete-orphan)½{‰ç­‰åQŒå¤§å®¶å¯ä»¥æ ¹æ®éœ€è¦æŸ¥é˜…官æ–ÒŽ(gu¨©)–‡æ¡£ã€?br />


laogao 2009-01-27 12:52 å‘表评论
]]>
[Pylons] SQLAlchemyèµäh­¥ - III. SQL Expression Languagehttp://www.aygfsteel.com/sean/archive/2009/01/26/252599.htmllaogaolaogaoMon, 26 Jan 2009 15:40:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/26/252599.htmlhttp://www.aygfsteel.com/sean/comments/252599.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/26/252599.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252599.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252599.html在介¾lSQLAlchemy最核心最有ä­h(hu¨¢n)值的ORM部分之å‰åQŒæˆ‘们冽ހå•过一éSQLAlchemyæä¾›çš„SQL Expression Language用法åQŒå°±ä»Žæœ€åŸºæœ¬çš„CRUDæ¥ä‹D例说明å§åQˆæŽ¥ç€ä¸Šä¸€½‹‡çš„½CÞZ¾‹åQ‰ï¼š

 1 from sqlalchemy import select,update,delete
 2 
 3 conn = engine.connect()
 4 book_ins = book_table.insert(values=dict(title=u'Groovy in Action'))
 5 author_ins = author_table.insert(values=dict(name=u'Andrew Glover'))
 6 conn.execute(book_ins)
 7 conn.execute(author_ins)
 8 book = conn.execute(select([book_table], book_table.c.title.like(u'Groovy%'))).fetchone()
 9 author = conn.execute(select([author_table])).fetchone()
10 bookauthor_ins = bookauthor_table.insert(values=dict(book_id=book[0],author_id=author[0]))
11 conn.execute(bookauthor_ins)
12 conn.execute(update(book_table,book_table.c.title==u'Groovy in Action'), title=u'Groovy in Action (中文�')
13 conn.execute(delete(bookauthor_table))
14 conn.close()

½Ž€å•说明一下代ç é€»è¾‘åQ?br />首先从engine建立˜qžæŽ¥åQŒç„¶åŽåšä¸¤ä¸ªinsert动作åQŒåˆ†åˆ«insert一æ¡book记录(titleä¸?Groovy in Action')和一æ¡author记录(nameä¸?Andrew Glover')åQŒè¿™ä¹‹åŽåˆ†åˆ«å†åšä¸¤æ¬¡selectåQŒå¾—到刚insert的这两æ¡è®°å½•åQŒå…¶ä¸­book记录的select用到了过滤æ¡ä»Óž¼Œç›¸å½“äº?WHERE book.title like 'Groovy%'"åQŒç„¶åŽæž„å»ÞZ¸€æ¡æ–°çš„insert语å¥åQŒç”¨äºŽinsert一æ¡bookauthor关系记录åQŒæŽ¥ä¸‹æ¥åQŒåšä¸€‹Æ¡updateåQŒå°†book.titleä¸?Groovy in Action'的更æ–îCØ“'Groovy in Action (中文ç‰?'åQŒæœ€åŽï¼Œåœ¨å…³é—­è¿žæŽ¥ä¹‹å‰ï¼Œåšä¸€‹Æ¡deleteåQŒåˆ é™¤bookauthor中的记录ã€?br />
在指定WHEREæ¡äšgæ—Óž¼Œ.cæ˜?columns的简写,所以book_table.c.title指代的就是book表的title列。更高çñ”的用法是采用"&"ã€?|"ã€?!"三个½W¦å·åQŒåˆ†åˆ«è¡¨½CºANDã€ORå’ŒNOTåQŒåŠ ä¸Šå¿…è¦çš„"("å’?)"å®žçŽ°å¤æ‚çš„æ¡ä»¶å®šä¹‰ã€‚由于传递给select()çš„ç¬¬ä¸€ä¸ªå‚æ•°æ˜¯ä¸ªliståQŒæ‰€ä»¥ä½ åº”该已ç»çŒœåˆ°äº†ï¼Œæˆ‘们也å¯ä»¥å¤šå¼ è¡¨åšå…³è”查询ã€?br />


laogao 2009-01-26 23:40 å‘表评论
]]>
[Pylons] SQLAlchemyèµäh­¥ - II. MetaDataå’ŒTypeshttp://www.aygfsteel.com/sean/archive/2009/01/26/252597.htmllaogaolaogaoMon, 26 Jan 2009 14:14:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/26/252597.htmlhttp://www.aygfsteel.com/sean/comments/252597.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/26/252597.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252597.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252597.html在sqlalchemy.schemaå’Œsqlalchemy.types˜q™ä¸¤ä¸ªmodule中,包å«äº†å®šä¹‰æ•°æ®åº“schema所需è¦çš„æ‰€æœ‰ç±»åQŒå¦‚Tableã€Columnã€Stringã€Textã€Dateã€Timeã€Boolean½{‰ã€‚还是æ¥çœ‹ä¸€ä¸ªä¾‹å­ï¼š

 1 from sqlalchemy.engine import create_engine
 2 from sqlalchemy.schema import MetaData, Table, Column, ForeignKey, Sequence
 3 from sqlalchemy.types import *
 4 
 5 engine = create_engine('postgres://test:test@localhost/test', echo=True)
 6 
 7 metadata = MetaData()
 8 metadata.bind = engine
 9 
10 book_table = Table('book', metadata,
11     Column('id', Integer, Sequence('seq_pk'), primary_key=True),
12     Column('title', Unicode(255), nullable=False),
13 )
14 
15 author_table = Table('author', metadata,
16     Column('id', Integer, Sequence('seq_pk'), primary_key=True),
17     Column('name', Unicode(255), nullable=False),
18 )
19 
20 bookauthor_table = Table('bookauthor', metadata,
21    Column('book_id', Integer, ForeignKey('book.id'), nullable=False),
22    Column('author_id', Integer, ForeignKey('author.id'), nullable=False),
23)
24
25metadata.create_all(checkfirst=True)

首先我们˜q˜æ˜¯create_engineåQŒç„¶åŽæ–°å»ÞZ¸€ä¸ªMetaData对象åQŒæŠŠengine¾l‘上去,接下æ¥ï¼Œå¼€å§‹åœ¨metadata中定义表¾l“æž„(metadataç”±Table构造函æ•îC¼ å…?åQŒæˆ‘们这里定义了3张表åQŒåˆ†åˆ«æ˜¯bookã€authorå’Œbookauthor关系è¡?“多对多â€?åQŒå…¶ä¸­æ–°å»ÞZ¸€ä¸ªSequence对象åQŒä¸“门处ç†ä¸»é”®ç”Ÿæˆã€‚æœ€åŽæˆ‘们通过执行metadata.create_all()åˆ›å¾æ•°æ®åº“表åQŒå‚æ•°checkfirst=True表示如果数æ®åº“相兛_¯¹è±¡å·²¾l存在,则ä¸é‡å¤æ‰§è¡Œåˆ›å¾ã€?br />
对于已ç»å­˜åœ¨äºŽæ•°æ®åº“中的表,我们å¯ä»¥é€šè¿‡ä¼ å…¥autoload=True傿•°åˆ°Tableæž„é€ å‡½æ•°çš„æ–¹å¼æ¥åŠ è½½çŽ°æœ‰çš„è¡¨ç»“æž„åˆ°metadata中,而ä¸å¿…挨个儿å†å†™ä¸€éColumn清å•ã€?br />
看到˜q™å„¿åQŒä½ ä¹Ÿè®¸è§‰å¾—æŒºéº»çƒ¦ï¼Œä¸æ˜¯ä¹ˆï¼ŸDjangoå’ŒRoR都是å¯ä»¥ç›´æŽ¥å®šä¹‰æ•°æ®model¾c»ï¼Œ™åºå¸¦ž®±æŠŠschema也定义了åQŒè€Œä¸æ˜¯åƒ˜q™æ ·å•独åŽÕd†™è¡¨ç»“构的schemaåQŒæ˜¾å¾—很"底层"。确实,˜q™æ ·ç”¨SQLAlchemyòq¶ä¸æ˜¯æœ€ä¼˜åŒ–的,SQLAlchemy本èínòq¶ä¸ä¼šè‡ªåŠ¨çš„å¸®ä½ åšå¾ˆå¤šäº‹åQŒä½†å®ƒåŸº¼‹€æ‰“得很牢。如果你感兴­‘£ï¼Œä¹Ÿå¯ä»¥å…ˆåŽÈœ‹ä¸€ä¸‹SQLAlchemy的扩展模å—ElixiråQŒé€šè¿‡ElixiråQŒä½ å¯ä»¥åƒRuby on Rails那样定义出实体和关系("Active Record")ã€?br />
在ç¨åŽçš„½W?éƒ¨åˆ†ä¸­ï¼Œæˆ‘ä»¬ä¼šåŽ»äº†è§£å¦‚ä½•ä»¥å£°æ˜Žæ–¹å¼æ¥æ›´ç´§å‡‘的定义我们的model/schema(0.5新特æ€?。鉴于笔者們֑于更强的控制力,所以在˜q™ä¸ª¾pÕdˆ—中就ä¸å޻介ç»SQLAlchemy的其他扩展模å—了åQŒå¦‚Elixirã€SQLSoup½{‰ï¼Œå¤§å®¶å¯ä»¥æ ÒŽ(gu¨©)®éœ€è¦åŽ»æ‰¾ä¸‹å®˜æ–¹æ–‡æ¡£ã€?br />


laogao 2009-01-26 22:14 å‘表评论
]]>
[Pylons] SQLAlchemyèµäh­¥ - I. Engine APIhttp://www.aygfsteel.com/sean/archive/2009/01/26/252592.htmllaogaolaogaoMon, 26 Jan 2009 12:46:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/26/252592.htmlhttp://www.aygfsteel.com/sean/comments/252592.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/26/252592.html#Feedback1http://www.aygfsteel.com/sean/comments/commentRss/252592.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252592.htmlORM是个大è¯é¢˜ï¼Œå¤§åˆ°å¯èƒ½å¥½å‡ æœ¬ä¹¦éƒ½è¯´ä¸å®Œã€‚SQLAlchemyåQŒåˆ«çœ‹å®ƒåˆšå‡ºåˆ?.5.2åQŒå·²ç„¶æ˜¯Python世界ORM的事实标准,å—到众多开å‘者和无数框架的é’çã€?br />
å¦‚æžœä¹‹å‰æ²¡æœ‰æˆ–很ž®‘接触SQLAlchemyåQŒé‚£ä¹ˆå­¦ä¹ Pylonså¯èƒ½æœ‰ç›¸å½“一部分旉™—´éƒ½ä¼šèŠ±åœ¨SQLAlchemy上。通常åQŒäh们选择Pylons或者TurboGearsè€Œä¸æ˜¯DjangoåQŒSQLAlchemyåœ¨è¿™äº›å†³å®šçš„èƒŒåŽæœ‰ç€å¾ˆé‡çš„分é‡ã€‚作为Pylons学习½W”记的一部分åQŒæŽ¥ä¸‹æ¥æˆ‘å°†åˆ?½‹‡éš½W”介¾lSQLAlchemyåQŒåˆ†åˆ«æ˜¯Engine APIã€Schema Management (MetaData/Types)ã€SQL Expression Languageå’ŒObject Relational Mapperã€‚æ­¤æ–‡äØ“½W?½‹‡ï¼Œé‡ç‚¹ä»‹ç»Engine APIã€?br />
¾cÖM¼¼Javaçš„JDBCåQŒPython也有一个类似的数æ®åº“访问接å£è§„范,那就是DB-API(ç›®å‰æ˜?.0)åQŒä¸åŒçš„常è§RDBMS都有½W¦åˆDB-API标准的Python库,比如PostgreSQL有psycopg2åQŒOracle有cx_Oracle½{‰ã€‚有了这个基¼‹€åQŒSQLAlchemy也就得以方便的通过DB-API˜qžæŽ¥ä¸åŒçš„æ•°æ®åº“ã€?br />
以PostgreSQLä¸ÞZ¾‹åQŒé€šè¿‡SQLAlchemyçš„Engine API讉K—®æ•°æ®åº“的代ç å¯ä»¥˜q™æ ·æ¥å†™åQ?br />
 1 from sqlalchemy.engine import create_engine
 2 
 3 engine = create_engine('postgres://user:pass@localhost/testdb')
 4 connection = engine.connect()
 5 connection.execute(
 6     """
 7     CREATE TABLE book
 8     (
 9       id serial NOT NULL,
10      title character varying(30) NOT NULL,
11      CONSTRAINT pk_book PRIMARY KEY (id)
12     );
13    """
14 )
15 connection.execute(
16     """
17     INSERT INTO book (title) VALUES (%s);
18     """,
19     "The Art of UNIX Programming"
20 )
21 rs = connection.execute("SELECT title FROM book")
22 for row in rs:
23     print "Book Title: ", row['title']
24 connection.close()

基本步骤ž®±æ˜¯create_engineã€connectã€executeå’ŒcloseåQŒæ²¡æœ‰å¾ˆç‰¹åˆ«çš„地方,ä¸è¿‡SQLAlchemyçš„Engine APIåQŒåÆˆä¸æ˜¯½Ž€å•çš„DBAPI调用åQŒè€Œæ˜¯åŒ…装了其他内容,如数æ®åº“˜qžæŽ¥æ± ï¼Œæˆ‘们å¯ä»¥åœ¨create_engineçš„æ—¶å€™æŒ‡å®šè¿žæŽ¥æ± å‚æ•°å’Œå…¶ä»–é¢å¤–é…¾|®ï¼Œ¾cÖM¼¼˜q™æ ·åQ?br />
engine = create_engine('postgres://user:pass@localhost/testdb', pool_size=10, convert_unicode=True)

¾cÖM¼¼Springçš„JdbcTemplateåQŒæ›´å¤šçš„æ—¶å€™ï¼Œ¾lŸä¸€ä½¿ç”¨SQLAlchemyçš„Engine APIè€Œä¸æ˜¯DB-APIèƒ½ç»™æˆ‘ä»¬å¸¦æ¥æ›´å¤§çš„絋zÀL€§ï¼Œé€šå¸¸ä¹Ÿæ›´æ–¹ä¾¿ã€æ›´å®‰å…¨ã€?br />


laogao 2009-01-26 20:46 å‘表评论
]]>
[Pylons] Routeså’ŒcontrolleråQŒä¸€ä¸ªç®€å•的例å­http://www.aygfsteel.com/sean/archive/2009/01/26/252583.htmllaogaolaogaoMon, 26 Jan 2009 08:21:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/26/252583.htmlhttp://www.aygfsteel.com/sean/comments/252583.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/26/252583.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252583.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252583.html在开始之å‰ï¼Œè¯´ç‚¹æå¤–è¯ï¼Œéšç€å¯¹Pylons了解的深入,你å¯èƒ½æ—¶ä¸æ—¶éœ€è¦çœ‹çœ‹ç›¸å…³ç»„ä»?软äšgåŒ…æ˜¯å¦æœ‰æ›´æ–°å‡ºæ¥åQŒæ–¹æ³•也ä¸å¤æ‚,通过"easy_install -U [¾l„äšgå]"å›_¯åQŒåœ¨å­¦ä¹ æˆ–者是开å‘过½E‹ä¸­åQŒæœ€å¥½æ˜¯ä¿æŒçŽ¯å¢ƒç›¸å¯¹è¾ƒæ–°åQŒç›´åˆ°å‡ºçŽ°ç›¸å¯¹å¤§çš„release或者峞®†è¿›å…¥äñ”å“部¾|²é˜¶ŒDüc€?br />
¾l§ç®‹ä»‹ç»Pylons¾l„äšgåQŒå…ˆçœ‹ä¸ªä¾‹å­ã€‚首先用"paster controller hello"增加一个controlleråQŒèµ\径中会增加出以下两个文äšgåQ?br />
controllers/hello.py
tests/functional/test_hello.py

分别对应新增的controller¾c»HelloController和功能测试类TestHelloControlleråQŒå®ƒä»¬åˆ†åˆ«ç‘ô承自WSGIController->BaseControllerå’ŒTestCase->TestControllerã€?br />
我们主è¦çœ‹hello.pyåQŒé»˜è®¤å†…容如下:
 1 import logging
 2 
 3 from pylons import request, response, session, tmpl_context as c
 4 from pylons.controllers.util import abort, redirect_to
 5 
 6 from newapp.lib.base import BaseController, render
 7 #from newapp import model
 8 
 9 log = logging.getLogger(__name__)
10 
11 class HelloController(BaseController):
12 
13     def index(self):
14         # Return a rendered template
15         #   return render('/template.mako')
16         # or, Return a response
17         return 'Hello World'

如果你的æœåŠ¡å™¨æ²¡æœ‰Ctrl-CåœæŽ‰åQŒé‚£ä¹ˆè¿™ä¸ªæ—¶å€™ä½ å·²ç»å¯ä»¥é€šè¿‡
http://127.0.0.1:5000/hello/index
看到该controller的处ç†ç»“果了(Hello World)ã€?br />
½Ž€å•改造一ä¸?7行:
        from pylons import config
        
return '<br/>'.join(config.keys())

我们ž®±å¯ä»¥åœ¨˜q”回™åµé¢ä¸Šæ˜¾½Cºå‡ºæ‰€æœ‰å¯ä»¥é€šè¿‡pylons.config讉K—®åˆ°çš„傿•°åˆ—表。出了返回文本,也å¯ä»¥é€šè¿‡render()æ–ÒŽ(gu¨©)³•交给™åµé¢æ¨¡æ¿å¼•擎生戙åµé¢åQŒä¹Ÿå¯ä»¥é€šè¿‡redirect_to()è·Œ™{到其他URLã€?br />
Pylons是如何找到该è¯äh±‚应该由HelloControllerçš„indexæ–ÒŽ(gu¨©)³•æ¥å¤„ç†çš„呢?˜q™èƒŒåŽå‘生了什么?½{”案ž®±æ˜¯Routesã€?br />
Routes的作者是Ben BangertåQŒæ˜¯Pylons框架三个主è¦ä½œè€?¾l´æŠ¤è€…之一åQŒæ—©æœŸçš„ç‰ˆæœ¬ä¸»è¦æ˜¯ä»¿ç…§Ruby on Railsçš„routes.rbå¼€å‘çš„åQŒæœ‰RoR¾l验的朋å‹å¯èƒ½ä¸€çœ¼å°±èƒ½å‘çŽ°å®ƒä»¬ä¹‹é—´çš„ç›æ€¼¼ä¹‹å¤„。目å‰Routes的最新版æ˜?.10.2ã€?br />
Pylons应用中,routing的酾|®åœ¨config/routing.pyåQŒé»˜è®¤ç”Ÿæˆçš„内容如下åQ?br />
 1 """Routes configuration
 2 
 3 The more specific and detailed routes should be defined first so they
 4 may take precedent over the more generic routes. For more information
 5 refer to the routes manual at http://routes.groovie.org/docs/
 6 """
 7 from pylons import config
 8 from routes import Mapper
 9 
10 def make_map():
11     """Create, configure and return the routes Mapper"""
12     map = Mapper(directory=config['pylons.paths']['controllers'],
13                  always_scan=config['debug'])
14     map.minimization = False
15     
16     # The ErrorController route (handles 404/500 error pages); it should
17     # likely stay at the top, ensuring it can always be resolved
18     map.connect('/error/{action}', controller='error')
19     map.connect('/error/{action}/{id}', controller='error')
20 
21     # CUSTOM ROUTES HERE
22 
23     map.connect('/{controller}/{action}')
24     map.connect('/{controller}/{action}/{id}')
25 
26     return map

在这个酾|®ä¸­åQŒå¯¹æˆ‘们刚æ‰çš„实例è“v到决定性作用的是第23行,我们的输入URLä¸?http://127.0.0.1:5000/hello/index"åQŒå…¶ä¸?/hello/index"通过"/{controller}/{action}"˜q™ä¸ªè¡¨è¾¾å¼match出controller为hello而action为index的解æžç»“果,从而在controllers目录扑ֈ°hello.pyåQŒå’Œå…¶ä¸­HelloControllerçš„indexæ–ÒŽ(gu¨©)³•åQŒè¿›è¡Œè°ƒç”¨ã€?br />
map.connect()在上é¢ä»£ç ä¸­ä½“现å‡ÞZ¸¤¿U用法:
map.connect('pattern', key=value) - 指定默认的controllerã€actionã€id½{?br />map.connect('pattern') - 直接指定pattern

pattern字符串å…è®”R€šé…½W¦ï¼Œé€šå¸¸åœ¨æœ€åŽä¸€ä¸ªå…ƒç´ ä¸ŠåQŒæ¯”å¦?/{controller}/{action}/{*url}'åQŒå°†åŽé¢çš„æ•´ä¸ªURL片段交给å‰é¢æŒ‡å®šçš„controller/action处ç†ã€‚除此以外,map.connect()˜q˜æ”¯æŒ?br />
1- "路径别å"åQŒå¦‚åQ?br />map.connect('name', 'pattern', [_static=True])
如果_staticè®¾äØ“"True"åQŒè¡¨½CÞZØ“"陿€å‘½åèµ\å¾?ã€?br />2- é¢å¤–çš„åŒ¹é…æ¡ä»Óž¼Œå¦‚:
map.connect('/{controller}/{action}/{id}', requirements={'year': '\d+',})
map.connect('/{controller}/{action}/{id}', conditions=dict(method=['GET','POST']))

所有的route优先¾U§äؓ从上åˆîC¸‹ã€‚Routes除了æä¾›è§£æž˜q›æ¥çš„URL的逻辑åQŒåœ¨æˆ‘们的controllerå’Œtemplate代ç ä¸­ï¼Œæˆ‘们˜q˜å¯ä»¥æ–¹ä¾¿çš„通过WebHelpersçš„url_for()æ–ÒŽ(gu¨©)³•计算相应的URLã€?br />
Routes 1.x中的有一些仿routes.rb功能ž®†ä¼šåœ?.0中被åŽÀLމåQŒåŒ…括Route Minimizationã€Route Memoryã€Implicit Defaults½{‰ã€‚如果有兴趣的è¯åQŒå¯ä»¥å‚考一下官æ–ÒŽ(gu¨©)–‡æ¡£ï¼Œ˜q™é‡Œž®×ƒ¸ä¸€ä¸€ä»‹ç»äº†ã€‚äØ“ä»€ä¹ˆè¦åŽÀLމåQŸå½“然主è¦çš„动机˜q˜æ˜¯å‡å°‘歧义åQŒé¿å…一些ä¸å¿…è¦çš„æØœæ·†ã€‚至于深层次的原因么åQŒå¯ä»¥å‚考Tim Peters《The Zen of Python》中的一å¥ç»å…¸çš„Python哲学åQšExplicit is better than implicit。什么?没有å¬è¯´˜q‡ï¼Ÿæ‰“å¼€python命ä×o行,输入"import this"åŽå›žè½¦ï¼Œæ…¢æ…¢ä½“会其中的é“ç†å§ã€?)




laogao 2009-01-26 16:21 å‘表评论
]]>
[Pylons] 默认™å¹ç›®¾l“æž„http://www.aygfsteel.com/sean/archive/2009/01/26/252579.htmllaogaolaogaoMon, 26 Jan 2009 04:33:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/26/252579.htmlhttp://www.aygfsteel.com/sean/comments/252579.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/26/252579.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252579.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252579.html大家新年好ï¼

åœ?a target="_blank" title="http://www.aygfsteel.com/sean/archive/2009/01/25/252561.html" href="/sean/archive/2009/01/25/252561.html">å‰ä¸€½‹‡éš½W?/a>中,大家了解了什么是PylonsåQŒæœ‰å“ªäº›ç‰¹ç‚¹åQŒä»Šå¤©ç¬”者ç‘ô¾l­ç»™ä»‹ç»é»˜è®¤ç”Ÿæˆçš„项目结构ã€?br />
通过Pasteåˆ›å¾æ–°çš„Pylons应用很简å•,ž®±æ˜¯ä¸€å?paster create -t pylons [应用å]"命ä×oåQŒå…¶ä¸?-t pylons"或者全¿U?--template=pylons"åQŒç”¨ä»¥å‘Šè¯‰Paste我们新å¾çš„项目,ž®†æ˜¯ä¸€ä¸ªPylons应用åQŒæˆ–者说åQŒä»Žä¸€ä¸ªé¢„定义好的Pylons默认™å¹ç›®æ¨¡æ¿ç”Ÿæˆã€‚如果你愿æ„åQŒä½ ä¹Ÿå¯ä»¥è‡ªå·±æ¥åˆ¶ä½œæ–°çš„æ¨¡æ¿ä»¥ç¬¦åˆéœ€è¦ã€?paster create --list-templates"å¯ä»¥æŸ¥çœ‹å½“å‰å¯ç”¨çš„æ¨¡æÑ€?br />
å‡å®šæˆ‘们新å¾çš„Pylons™å¹ç›®å称为NewAppåQŒé‚£ä¹ˆæ‰§è¡?paster create -t pylons NewApp"åŽï¼Œæˆ‘们ž®†å¾—åˆîC¸€ä¸ªæ–°çš„NewApp目录åQŒå…¶ä¸­åŒ…å«ä¸€ä¸ªdocs目录(文档)ã€ä¸€ä¸ªnewapp目录(代ç )ã€ä¸€ä¸ªNewApp.egg-info目录(元数æ?和一些顶¾U§é…¾|®æ–‡ä»¶ã€?br />
在开å‘过½E‹ä¸­åQŒæˆ‘们ç»å¸æ€¼šç”¨åˆ°çš„æ˜¯ä»£ç ç›®å½•(˜q™é‡Œæ˜¯newapp)å’Œä½äºŽé¡¹ç›®æ ¹ç›®å½•下的development.iniå’Œtest.iniæ–‡äšg了。注æ„这里newapp的大ž®å†™åQŒPylons在生æˆé¡¹ç›®çš„æ—¶å€™ï¼Œä¸è®ºä½ æŒ‡å®šçš„™å¹ç›®å称大å°å†™æ˜¯æ€Žæ ·åQŒè¿™é‡Œä¼šè‡ªåЍ.lower()转å°å†™ï¼Œåªæœ‰™å¹ç›®™å¶çñ”路径和eggä¿¡æ¯ä¼šä¿ç•™åŽŸå§‹å¤§ž®å†™åQŒç¬”è€…è®¤ä¸ø™¿™æ›´åŠ ½W¦åˆWeb应用的natureã€?br />
代ç ç›®å½•下包括configã€controllersã€libã€modelã€publicã€templateså’Œtestså­ç›®å½•,分别用于存放é…ç½®(如环境ã€ä¸­é—´äšgã€èµ\径查æ‰ùN€»è¾‘)ã€æŽ§åˆ¶å™¨(处ç†è¯äh±‚)ã€å…¨å±€è¾…助代ç (全局å˜é‡ã€helpers½{?ã€æ¨¡åž?åŽå°æ•°æ®è®‰K—®)ã€é™æ€é¡µé?媒体文äšgã€é¡µé¢æ¨¡æ¿å’Œ‹¹‹è¯•代ç ã€?br />
最åŽè¯´è¯´iniæ–‡äšgåQšé»˜è®¤ç”Ÿæˆçš„development.iniå’Œtest.ini™å‘Öæ€ä¹‰åˆ†åˆ«å¯¹åº”å¼€å‘å’Œ‹¹‹è¯•需è¦çš„基本é…ç½®åQŒæˆ‘们å¯ä»¥é€šè¿‡ä¿®æ”¹ç›¸åº”çš„å‚æ•°é…¾|®æ¥æŒ‡å®šå…·ä½“讑֮šåQŒå¦‚æœåС噍IP和端å£ã€æ•°æ®åº“˜qžæŽ¥ã€æ—¥å¿—等。看到这里你也许会问åQŒé‚£ä¹ˆäñ”å“环境呢åQŸç­”案是默认没有生æˆåQŒä½ å¯ä»¥ä»Ždevelopment.ini修改æˆéœ€è¦çš„产å“环境é…ç½®åQŒä¹Ÿå¯ä»¥é€šè¿‡paster make-config newapp production.ini生æˆä¸€ä¸ªé»˜è®¤çš„产å“环境典型é…ç½®ã€?br />
以development.iniä¸ÞZ¾‹åQŒPylonsçš„iniæ–‡äšg主è¦åŒ…括4个部分的内容åQ?br />
1- å…¨å±€é»˜è®¤å‚æ•°åQŒå¦‚
[DEFAULT]
debug 
= true
# Uncomment and replace with the address which should receive any error reports
#email_to 
= you@yourdomain.com
smtp_server 
= localhost
error_email_from 
= paste@localhost



2- æœåС噍酾|®ï¼Œå¦?br />
[server:main]
use 
= egg:Paste#http
host 
= 127.0.0.1
port 
= 5000



3- 应用½E‹åºé…ç½®åQŒå¦‚
[app:main]
use 
= egg:NewApp
full_stack 
= true

cache_dir 
= %(here)s/data
beaker.session.key 
= newapp
beaker.session.secret 
= somesecret

# If you'd like to fine-tune the individual locations of the cache data dirs
# for the Cache data
, or the Session saves, un-comment the desired settings
# here:
#beaker.cache.data_dir 
= %(here)s/data/cache
#beaker.session.data_dir 
= %(here)s/data/sessions

# SQLAlchemy database URL
sqlalchemy.url 
= sqlite:///%(here)s/development.db

# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
# Debug mode will enable the interactive debugging tool
, allowing ANYONE to
# execute malicious code after an exception is raised.
#set debug 
= false
½Ž€å•说明一下,˜q™é‡Œçš„full_stack讄¡½®ä¸ºtrue表示打开交互å¼è°ƒè¯•和错误报告½{‰åŠŸèƒ½ï¼Œ"%(here)s"ä¼šè¢«æ›¿æ¢æˆé¡¹ç›®æ‰€åœ¨èµ\径,¾cÖM¼¼ç›¸å¯¹è·¯å¾„url中的"."转ç»å¯¹èµ\径,而beaker.*为酾|®ä¼šè¯ç›¸å…³çš„讑֮šåQŒå¦‚¾~“å­˜ã€cookie基本内容½{‰ã€‚对于äñ”å“环境æ¥è¯ß_¼Œæ¯”较é‡è¦çš„一个酾|®æ˜¯"set debug=false"åQŒå¦åˆ™ä¸€æ—¦å‡ºçŽ°å¼‚å¸¸ï¼Œäº¤äº’å¼è°ƒè¯•将使得æ”Õd‡»è€…能够执行系¾lŸå‘½ä»¤ã€?br />
4- 日志åQŒå¦‚
[loggers]
keys 
= root, routes, newapp, sqlalchemy

[handlers]
keys 
= console

[formatters]
keys 
= generic

[logger_root]
level 
= INFO
handlers 
= console

[logger_routes]
level 
= INFO
handlers 
=
qualname 
= routes.middleware
# 
"level = DEBUG" logs the route matched and routing variables.

[logger_newapp]
level 
= DEBUG
handlers 
=
qualname 
= newapp

[logger_sqlalchemy]
level 
= INFO
handlers 
=
qualname 
= sqlalchemy.engine
# 
"level = INFO" logs SQL queries.
# 
"level = DEBUG" logs SQL queries and results.
# 
"level = WARN" logs neither.  (Recommended for production systems.)

[handler_console]
class 
= StreamHandler
args 
= (sys.stderr,)
level 
= NOTSET
formatter 
= generic

[formatter_generic]
format 
= %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
datefmt 
= %H:%M:%S

OKåQŒè¿™ä¸€½‹‡å°±å…ˆè®²åˆ°è¿™å„¿ï¼Œä¸‹ä¸€½‹‡å°†ä»‹ç»Routeså’Œcontrollerã€?br />



laogao 2009-01-26 12:33 å‘表评论
]]>
[Pylons] ½Ž€ä»?安装指å—http://www.aygfsteel.com/sean/archive/2009/01/25/252561.htmllaogaolaogaoSun, 25 Jan 2009 12:05:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/25/252561.htmlhttp://www.aygfsteel.com/sean/comments/252561.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/25/252561.html#Feedback1http://www.aygfsteel.com/sean/comments/commentRss/252561.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252561.htmlPylons是一个Python语言的Web应用½E‹åºæ¡†æž¶åQŒå¦‚果你½Ž€å•了解过Ruby on Railså’ŒDjangoåQŒä½ å¤§æ¦‚会问åQŒPylons有什么ä¸ä¸€æ ·å‘¢åQŸPylons最大的特点是模å—化åQŒå°†å¤„ç†Web应用环境下ä¸åŒé¢†åŸŸã€ä¸åŒé—®é¢˜çš„软äšg包集æˆåœ¨ä¸€èµøP¼Œå½¢æˆä¸€ä¸ªæ•´ä½“,在æä¾›ä¸€æ½å­è§£å†³æ–ÒŽ(gu¨©)¡ˆçš„åŒæ—Óž¼Œä¸é˜»¼„你选择别的替代¾l„äšg。å¦å¤–,Pylons是目å‰å¯¹WSGIæ ‡å‡†æ”¯æŒæœ€å¥½çš„æ¡†æž¶ä¹‹ä¸€åQŒæœªæ¥çš„TurboGears 2.0也会åŸÞZºŽPylonsæž„å¾ã€?br />
Pylons从Ruby on Rails借鉴了丞®‘东西,比如RoutesåQŒæ¯”如WebHelpersåQŒä»Žè¡¨é¢çœ‹æ›´åƒæ˜¯Python版的RoRåQŒä¸˜q‡åº•下的架构应该说更加轻é‡å’Œç‰|´»åQŒå› ä¸ÞZ½ å¯ä»¥ç‰|´»é€‰æ‹©è‡ªå·±ç†Ÿæ?zh¨¨n)‰æˆ–者更贴和具体应用实际的组ä»Óž¼Œä»ŽORMåˆ°é¡µé¢æ¨¡æ¿ï¼ŒPylonsåªæ˜¯æŽ¨èä¸€äº›å¤§å®¶æ™®éæ¯”较认å¯çš„选项åQŒä½†òq¶ä¸å¼ºåˆ¶ä½ ä‹É用它们ã€?br />
说完和Ruby on Rails的异åŒï¼Œå½“然也è¦å›žè¿‡å¤´æ¥è¯´è¯´åŒæ ·æ˜¯Python¾~–写的Djangoã€‚å¦‚æžœä½ åªæ˜¯æƒŒ™¿…速的构å¾ä¸€ä¸ªå¯ä»¥æ”¯æ’‘大é‡è®¿é—®çš„Web应用åQŒDjango是个ä¸é”™çš„选择åQŒä½†å’ŒRoRä¸€æ øP¼Œä½ åœ¨å¾ˆå¤§½E‹åº¦ä¸Šè¢«é™åˆ¶åœ¨ä¸€å®šçš„pattern中:如果你按照Djangoçš„æ€èµ\åŽÕd®žçŽîC½ çš„应用,你会很happyåQ›ä½†ä¸€æ—¦ä½ è§‰å¾—æŸä¸ª¾l„äšgä½ ä¸å–œæ¬¢ã€ä¸½W¦åˆæŸä¸ªå®žé™…è¦æ±‚åQŒæƒ³è¦æ¥ç‚¹å®šåˆÓž¼Œä½ å°±ä¼šè§‰å¾—有些äŽ×ä¸å¼€æ‹Œ™„šåQŒæˆ–者工½E‹æµ©å¤§ã€‚ç›®å‰æ„Ÿè§‰Django比较ä¸çˆ½çš„地æ–ÒŽ(gu¨©)œ‰åQšé¡µé¢æ¨¡æ¿è¾ƒå¼±ï¼Œè¡¨çŽ°åŠ›æœ‰äº›ä¸­‘»I¼Œä¹Ÿæœ‰äºø™¯´å¤Ÿç”¨äº†ï¼›ORMç›®å‰æ˜¯è‡ªå·Þqš„一套,暂时没有æˆç†Ÿçš„SQLAlchemy支æŒåQŒéœ€è¦ç¬¬ä¸‰æ–¹åŒ…或者自己åšåQ›ä»Žæž¶æž„上,Django对MVC的解è¯ÀL˜¯MTV(Model-Template-View)åQŒå¤§å®‰™ƒ½å«ä½œcontroller的东东,在Django的世界里是viewåQŒä»¥è‡³äºŽæ¯æ¬¡å’Œåˆ«äºø™§£é‡Šï¼Œéƒ½è¦å¤šè´¹ä¸€ç•ªå£èˆŒã€?br />
Pylonsç›®å‰ç‰ˆæœ¬æ˜?.9.7(rc4)åQŒä¸»è¦ç”¨åˆ°çš„½W¬ä¸‰æ–?独立¾l„äšg有Pasteã€Routesã€Beakerã€Makoã€FormEncodeã€WebHelperså’ŒSQLAlchemy。安装方法如下:

首先你必™åÀLœ‰Python(2.3+)åQŒç„¶åŽä½ å¯ä»¥é€‰æ‹©ç›´æŽ¥easy_install Pylons或者新å»ÞZ¸€ä¸ªVirtual EnvironmentåQŒå’Œ¾pÈ»Ÿä¸­çš„Python环境隔离开åQŒä¾èµ–的包å¯ä»¥ç‹¬ç«‹å‡¾U§ã€‚这里我们按照åŽä¸€¿Uæ–¹å¼ï¼Œå¦‚果你是½W¬ä¸€‹Æ¡ä‹É用PylonsåQŒå¾è®®ä½ ä¹Ÿåœ¨ç‹¬ç«‹Python virtualenv中安装ã€?br />
1- easy_install virtualenv (˜q™å°†å®‰è£…Python虚拟环境工具)
2- python virtualenv.py ENV (åˆ›å¾æ–°çš„虚拟环境。这里的ENV是你新å¾è™šæ‹ŸçŽ¯å¢ƒçš„èµ\径,å¦?mydevenv")
3- source ENV/bin/activate (‹È€‹z»è™šæ‹ŸçŽ¯å¢ƒã€‚å¦‚æžœæ˜¯Windowsçš„è¯åQŒè¿™é‡Œéœ€è¦æ‰§è¡ŒENV\bin\activate.bat)
4- easy_install Pylons (˜q™é‡Œä½¿ç”¨çš„æ˜¯è™šæ‹ŸçŽ¯å¢ƒçš„easy_install安装)

如果你觉得上é¢çš„æ­¥éª¤éºÈƒ¦åQŒPylonså¼€å‘团队æä¾›äº†ä¸€ä¸ªè„šæœ¬æ¥å¤„ç†å®‰è£…˜q‡ç¨‹åQŒä¸‹è½½åŽç”¨Python执行å›_¯åQ?br />http://www.pylonshq.com/download/0.9.7/go-pylons.py

如果需è¦SQLAlchemyåQŒåˆ™å†æ‰§è¡Œä¸€ä¸?br />easy_install SQLAlchemy

安装æˆåŠŸåŽï¼Œé€šè¿‡
paster create -t pylons [应用å]
å›_¯æ–°å¾Web应用ä¸ÀL¡†æžÓž¼Œç„¶åŽcd到应用下åQŒé€šè¿‡
paster serve --reload development.ini
å¯åЍWebæœåŠ¡åQŒé»˜è®¤åœ°å€åœ?br />http://127.0.0.1:5000/

更详¾l†çš„ä¿¡æ¯åQŒå¯å‚考Pylons™å¹ç›®ä¸»é¡µåQ?br />http://pylonshq.com/

éšç€ä½¿ç”¨çš„æ·±å…¥ï¼Œ½W”者还会陆¾l­å¯¹Pylons和其他相关组件进行进一步的介ç»ã€‚ç¥å„ä½å†œåŽ†æ–°å¹´å¿«ä¹åQ?br />



laogao 2009-01-25 20:05 å‘表评论
]]>
[备忘] 如何¼‹®å®šå½“å‰Python环境的site-packages目录http://www.aygfsteel.com/sean/archive/2009/01/23/252479.htmllaogaolaogaoFri, 23 Jan 2009 11:25:00 GMThttp://www.aygfsteel.com/sean/archive/2009/01/23/252479.htmlhttp://www.aygfsteel.com/sean/comments/252479.htmlhttp://www.aygfsteel.com/sean/archive/2009/01/23/252479.html#Feedback0http://www.aygfsteel.com/sean/comments/commentRss/252479.htmlhttp://www.aygfsteel.com/sean/services/trackbacks/252479.html有时我们需è¦åЍæ€çš„¼‹®å®šå½“å‰é‡‡ç”¨çš„Python˜q行时环境对应的site-packages目录åQŒåœ¨Python代ç ä¸­ï¼Œå¯ä»¥˜q™æ ·åšï¼š

from distutils.sysconfig import get_python_lib
print get_python_lib()

备忘�br />


laogao 2009-01-23 19:25 å‘表评论
]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ¼Ó²éÏØ| ÏæÒõÏØ| ¿ª½­ÏØ| ÎäÒÄɽÊÐ| ä»Ë®ÏØ| Ç­Î÷| À¼Æº| ´ó·½ÏØ| ÆÎÌïÊÐ| È«½·ÏØ| ÅÊÖ¦»¨ÊÐ| ºÍÆ½Çø| ¸·ÐÂÊÐ| ÔÞ»ÊÏØ| Îâ½­ÊÐ| ¸»Ô£ÏØ| Á¬½­ÏØ| ¸ß´¾ÏØ| ¶«ÀöÇø| Þ»³ÇÊÐ| °×ºÓÏØ| ¿µÂíÏØ| »ÔÏØÊÐ| ´óÍ¬ÏØ| ¸§ÄþÏØ| ʼÐËÏØ| ·îÏÍÇø| ¼ªÂ¡ÏØ| ¹ãË®ÊÐ| ä¬ÄÏÊÐ| ãå´¨ÏØ| ÉÛÑôÊÐ| ½¨µÂÊÐ| ¹ãÔªÊÐ| Ë«ÁÉÊÐ| ÕÄÆ½ÊÐ| ¾£ÖÝÊÐ| ÃçÀõÊÐ| Íâ»ã| ¹È³ÇÏØ| ÌÒÔ´ÏØ|