diff --git a/.idea/workspace.xml b/.idea/workspace.xml index b9c9e61..a609643 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -349,7 +349,7 @@ - + diff --git a/.vscode/.ropeproject/config.py b/.vscode/.ropeproject/config.py new file mode 100644 index 0000000..d1e8f3d --- /dev/null +++ b/.vscode/.ropeproject/config.py @@ -0,0 +1,100 @@ +# The default ``config.py`` +# flake8: noqa + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', + '.hg', '.svn', '_svn', '.git', '.tox'] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + #prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + #prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + #prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs['save_objectdb'] = True + prefs['compress_objectdb'] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs['automatic_soa'] = True + # The depth of calls to follow in static object analysis + prefs['soa_followed_calls'] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs['perform_doa'] = True + + # Rope can check the validity of its object DB when running. + prefs['validate_objectdb'] = True + + # How many undos to hold? + prefs['max_history_items'] = 32 + + # Shows whether to save history across sessions. + prefs['save_history'] = True + prefs['compress_history'] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs['indent_size'] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs['extension_modules'] = [] + + # Add all standard c-extensions to extension_modules list. + prefs['import_dynload_stdmods'] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs['ignore_syntax_errors'] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs['ignore_bad_imports'] = False + + # If `True`, rope will insert new module imports as + # `from import ` by default. + prefs['prefer_module_from_imports'] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs['split_imports'] = False + + # If `True`, rope will sort imports alphabetically by module name + # instead of alphabetically by import statement, with from imports + # after normal imports. + prefs['sort_imports_alphabetically'] = False + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/.vscode/settings.json b/.vscode/settings.json index d6b1940..32cbf34 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,7 @@ // 将设置放入此文件中以覆盖默认值和用户设置。 { + "python.pythonPath": "E:\\Program Files (x86)\\Python\\python.exe", + "python.linting.enabled": true, + "python.linting.lintOnSave": false, + "python.linting.flake8Enabled": true } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..eab2057 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "0.1.0", + "command": "npm", + "isShellCommand": true, + "showOutput": "always", + "suppressTaskName": true, + "tasks": [ + { + "taskName": "install", + "args": ["install"] + }, + { + "taskName": "update", + "args": ["update"] + }, + { + "taskName": "test", + "args": ["run", "test"] + } + ] +} \ No newline at end of file diff --git a/awesome-python3-webapp/www/__pycache__/coroweb.cpython-35.pyc b/awesome-python3-webapp/www/__pycache__/coroweb.cpython-35.pyc index 94073f6..99489d4 100644 Binary files a/awesome-python3-webapp/www/__pycache__/coroweb.cpython-35.pyc and b/awesome-python3-webapp/www/__pycache__/coroweb.cpython-35.pyc differ diff --git a/awesome-python3-webapp/www/__pycache__/handlers.cpython-35.pyc b/awesome-python3-webapp/www/__pycache__/handlers.cpython-35.pyc index 47f48f3..b73f8a6 100644 Binary files a/awesome-python3-webapp/www/__pycache__/handlers.cpython-35.pyc and b/awesome-python3-webapp/www/__pycache__/handlers.cpython-35.pyc differ diff --git a/awesome-python3-webapp/www/__pycache__/orm.cpython-35.pyc b/awesome-python3-webapp/www/__pycache__/orm.cpython-35.pyc index 035a2fc..576a622 100644 Binary files a/awesome-python3-webapp/www/__pycache__/orm.cpython-35.pyc and b/awesome-python3-webapp/www/__pycache__/orm.cpython-35.pyc differ diff --git a/awesome-python3-webapp/www/app.py b/awesome-python3-webapp/www/app.py index 10d22e7..92cae8b 100644 --- a/awesome-python3-webapp/www/app.py +++ b/awesome-python3-webapp/www/app.py @@ -1,76 +1,58 @@ -import logging -import asyncio -import json -import os -import time -from aiohttp import web +import logging; logging.basicConfig(level=logging.INFO) + +import asyncio, os, json, time from datetime import datetime + +from aiohttp import web from jinja2 import Environment, FileSystemLoader import orm from coroweb import add_routes, add_static -logging.basicConfig(level=logging.INFO) - -# def index(request): -# return web.Response(body='你好'.encode(encoding='utf-8'), -# headers={'Content-Type': 'text/html;charset=utf-8'}) - - def init_jinja2(app, **kw): - logging.info('init jinja2....') - options = dict(autoescape=kw.get('autoescape', True), - block_start_string=kw.get('block_start_string', '{%'), - block_end_string=kw.get('block_end_string', '%}'), - variable_start_string=kw.get('variable_start_string', '{{'), - variable_end_string=kw.get('variable_end_string', '}}'), - auto_reload=kw.get('auto_reload', True)) + logging.info('init jinja2...') + options = dict( + autoescape = kw.get('autoescape', True), + block_start_string = kw.get('block_start_string', '{%'), + block_end_string = kw.get('block_end_string', '%}'), + variable_start_string = kw.get('variable_start_string', '{{'), + variable_end_string = kw.get('variable_end_string', '}}'), + auto_reload = kw.get('auto_reload', True) + ) path = kw.get('path', None) - # logging.info('set jinja2 template path: %s' % path) if path is None: - path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), 'templates') + path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates') logging.info('set jinja2 template path: %s' % path) env = Environment(loader=FileSystemLoader(path), **options) filters = kw.get('filters', None) if filters is not None: for name, f in filters.items(): env.filters[name] = f - app['__templates__'] = env - + app['__templating__'] = env -@asyncio.coroutine -def logger_factory(app, handler): - def logger(request): +async def logger_factory(app, handler): + async def logger(request): logging.info('Request: %s %s' % (request.method, request.path)) # await asyncio.sleep(0.3) - return handler(request) - + return (await handler(request)) return logger - -@asyncio.coroutine -def data_factory(app, handler): - def parse_data(request): +async def data_factory(app, handler): + async def parse_data(request): if request.method == 'POST': if request.content_type.startswith('application/json'): - request.__data__ = request.json() + request.__data__ = await request.json() logging.info('request json: %s' % str(request.__data__)) - elif request.content_type.startswith( - 'application/x-www-form-urlencoded'): - request.__data__ = request.post() + elif request.content_type.startswith('application/x-www-form-urlencoded'): + request.__data__ = await request.post() logging.info('request form: %s' % str(request.__data__)) - return handler(request) - + return (await handler(request)) return parse_data - -@asyncio.coroutine -def response_factory(app, handler): - def response(request): +async def response_factory(app, handler): + async def response(request): logging.info('Response handler...') - r = handler(request) - logging.info(type(r)) + r = await handler(request) if isinstance(r, web.StreamResponse): return r if isinstance(r, bytes): @@ -86,15 +68,11 @@ def response(request): if isinstance(r, dict): template = r.get('__template__') if template is None: - resp = web.Response(body=json.dumps( - r, ensure_ascii=False, - default=lambda o: o.__dict__).encode('utf-8')) + resp = web.Response(body=json.dumps(r, ensure_ascii=False, default=lambda o: o.__dict__).encode('utf-8')) resp.content_type = 'application/json;charset=utf-8' return resp else: - resp = web.Response( - body=app['__templating__'].get_template(template).render( - **r).encode('utf-8')) + resp = web.Response(body=app['__templating__'].get_template(template).render(**r).encode('utf-8')) resp.content_type = 'text/html;charset=utf-8' return resp if isinstance(r, int) and r >= 100 and r < 600: @@ -107,10 +85,8 @@ def response(request): resp = web.Response(body=str(r).encode('utf-8')) resp.content_type = 'text/plain;charset=utf-8' return resp - return response - def datetime_filter(t): delta = int(time.time() - t) if delta < 60: @@ -124,28 +100,18 @@ def datetime_filter(t): dt = datetime.fromtimestamp(t) return u'%s年%s月%s日' % (dt.year, dt.month, dt.day) - -@asyncio.coroutine -def init(loop): - orm.create_pool(loop=loop, - host='localhost', - post=3306, - user='sa', - password='P@ssw0rd', - db='awesome') - app = web.Application(loop=loop, - middlewares=[ - logger_factory, response_factory - ]) +async def init(loop): + await orm.create_pool(loop=loop, host='127.0.0.1', port=3306, user='sa', password='P@ssw0rd', db='awesome') + app = web.Application(loop=loop, middlewares=[ + logger_factory, response_factory + ]) init_jinja2(app, filters=dict(datetime=datetime_filter)) add_routes(app, 'handlers') add_static(app) - # app.router.add_route("GET", "/", index) - srv = yield from loop.create_server(app.make_handler(), '127.0.0.1', 9003) - logging.info('Server started at http://127.0.0.1:9003') + srv = await loop.create_server(app.make_handler(), '127.0.0.1', 9000) + logging.info('server started at http://127.0.0.1:9000...') return srv - loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) -loop.run_forever() +loop.run_forever() \ No newline at end of file diff --git a/awesome-python3-webapp/www/coroweb.py b/awesome-python3-webapp/www/coroweb.py index 4487ebf..dd54ed3 100644 --- a/awesome-python3-webapp/www/coroweb.py +++ b/awesome-python3-webapp/www/coroweb.py @@ -10,6 +10,10 @@ def get(path): + ''' + Define decorator @get('/path') + ''' + def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): @@ -23,6 +27,10 @@ def wrapper(*args, **kw): def post(path): + ''' + Define decorator @post('/path') + ''' + def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): @@ -71,7 +79,6 @@ def has_request_arg(fn): sig = inspect.signature(fn) params = sig.parameters found = False - for name, param in params.items(): if name == 'request': found = True @@ -84,71 +91,9 @@ def has_request_arg(fn): % (fn.__name__, str(sig))) return found -# class RequestHandler(object): -# def __init__(self, app, fn): -# self._app = app -# self._func = fn -# self._has_request_arg = has_request_arg(fn) -# self._has_var_kw_arg = has_var_kw_arg(fn) -# self._has_named_kw_args = has_named_kw_args(fn) -# self._named_kw_args = get_named_kw_args(fn) -# self._required_kw_args = get_required_kw_args(fn) -# -# def __call__(self, request): -# kw = None -# if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args: -# if request.method == 'POST': -# if not request.content_type: -# return web.HTTPBadRequest('Missing content-type') -# ct = request.content_type.lower() -# if ct.startswith('application/json'): -# params = request.json() -# if not isinstance(params, dict): -# return web.HTTPBadRequest('JSON body must be object.') -# kw = params -# elif ct.startswith( -# 'application/x-www-form-urlencoded') or ct.startswith( -# 'multipart/form-data'): -# params = request.post() -# kw = dict(**params) -# else: -# return web.HTTPBadRequest('Unsupported Content-Type:%s' % -# request.content_type) -# if request.method == 'GET': -# qs = request.quert_string -# if qs: -# kw = dict() -# for k, v in parse.parse_qs(qs, True).items(): -# kw[k] = v[0] -# if kw is None: -# kw = dict(**request.match_info) -# else: -# if not self._has_var_kw_arg and self._named_kw_args: -# copy = dict() -# for name in self._named_kw_args: -# if name in kw: -# copy[name] = name -# kw = copy -# for k, v in request.match_info.items(): -# if k in kw: -# logging.warning( -# 'Duplicate arg name in named arg and kw args: %s' % k) -# kw[k] = v -# if self._has_request_arg: -# kw['request'] = request -# if self._required_kw_args: -# for name in self._required_kw_args: -# if name not in kw: -# return web.HTTPBadRequest('Missing argument:%s' % name) -# logging.info('Call with args :%s ' % str(kw)) -# try: -# r = self._func(**kw) -# return r -# except Exception as e: -# return dict(error=e.error, data=e.data, message=e.message) - class RequestHandler(object): + logging.info('RequestHandler Start....') def __init__(self, app, fn): self._app = app self._func = fn @@ -158,6 +103,9 @@ def __init__(self, app, fn): self._named_kw_args = get_named_kw_args(fn) self._required_kw_args = get_required_kw_args(fn) + logging.info('RequestHandler init .... ') + logging.info('object %s' % str(object)) + async def __call__(self, request): kw = None if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args: @@ -170,14 +118,11 @@ async def __call__(self, request): if not isinstance(params, dict): return web.HTTPBadRequest('JSON body must be object.') kw = params - elif ct.startswith( - 'application/x-www-form-urlencoded') or ct.startswith( - 'multipart/form-data'): + elif ct.startswith('application/x-www-form-urlencoded') or ct.startswith('multipart/form-data'): params = await request.post() kw = dict(**params) else: - return web.HTTPBadRequest('Unsupported Content-Type: %s' % - request.content_type) + return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type) if request.method == 'GET': qs = request.query_string if qs: @@ -197,52 +142,52 @@ async def __call__(self, request): # check named arg: for k, v in request.match_info.items(): if k in kw: - logging.warning( - 'Duplicate arg name in named arg and kw args: %s' % k) + logging.warning('Duplicate arg name in named arg and kw args: %s' % k) kw[k] = v if self._has_request_arg: kw['request'] = request # check required kw: if self._required_kw_args: for name in self._required_kw_args: - if not name in kw: + if name not in kw: return web.HTTPBadRequest('Missing argument: %s' % name) logging.info('call with args: %s' % str(kw)) try: r = await self._func(**kw) return r - except APIError as e: + except Exception as e: return dict(error=e.error, data=e.data, message=e.message) def add_static(app): path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static') app.router.add_static('/static/', path) - logging.info('add static %s => %s ' % ('/static/', path)) + logging.info('add static %s => %s' % ('/static/', path)) def add_route(app, fn): method = getattr(fn, '__method__', None) path = getattr(fn, '__route__', None) + logging.info('path:%s,method:%s' % (path,method)) if path is None or method is None: raise ValueError('@get or @post not defined in %s.' % str(fn)) - if not asyncio.iscoroutinefunction(fn) and not inspect.signature(fn): + if not asyncio.iscoroutinefunction(fn) and not inspect.isgeneratorfunction(fn): fn = asyncio.coroutine(fn) logging.info('add route %s %s => %s(%s)' % (method, path, fn.__name__, ', '.join(inspect.signature(fn).parameters.keys()))) + # logging.info('method: %s,fn: %s' % (method,fn)) app.router.add_route(method, path, RequestHandler(app, fn)) -def add_routes(app, moudle_name): - n = moudle_name.rfind('.') - # logging.info(' n %s ' % str(n)) +def add_routes(app, module_name): + n = module_name.rfind('.') if n == (-1): - mod = __import__(moudle_name, globals(), locals()) + mod = __import__(module_name, globals(), locals()) else: - name = moudle_name[n + 1:] + name = module_name[n + 1:] mod = getattr( - __import__(moudle_name[:n], globals(), locals(), [name]), name) + __import__(module_name[:n], globals(), locals(), [name]), name) for attr in dir(mod): if attr.startswith('_'): continue diff --git a/awesome-python3-webapp/www/handlers.py b/awesome-python3-webapp/www/handlers.py index 3ba13dd..f3f6833 100644 --- a/awesome-python3-webapp/www/handlers.py +++ b/awesome-python3-webapp/www/handlers.py @@ -1,18 +1,25 @@ -import re -import time -import json -import logging -import hashlib -import base64 -import asyncio +import re, time, json, logging, hashlib, base64, asyncio from coroweb import get, post from models import User, Comment, Blog, next_id +# @get('/') +# async def index(request): +# logging.info('users') +# users = await User.findAll() +# return {'__template__': 'test.html', 'users': users} +# +# +# @get('/test') +# async def index(request): +# logging.info('test') +# users = await User.findAll() +# return {'__template__': 'test.html', 'users': users} + +# 测试 @get('/') -def index(request): - logging.info('test User.findAll()') - users = User.findAll() +async def index(request): + users = await User.findAll() return {'__template__': 'test.html', 'users': users} diff --git a/awesome-python3-webapp/www/orm.py b/awesome-python3-webapp/www/orm.py index c5a54ff..8b33dd5 100644 --- a/awesome-python3-webapp/www/orm.py +++ b/awesome-python3-webapp/www/orm.py @@ -9,54 +9,60 @@ logging.basicConfig(level=logging.INFO) -@asyncio.coroutine -def create_pool(loop, **kw): +async def create_pool(loop, **kw): logging.info('create database connection pool...') global __pool - __pool = yield from aiomysql.create_pool( - host=kw.get('host', 'localhost'), - port=kw.get('port', 3306), - user=kw['user'], - password=kw['password'], - db=kw['db'], - charset=kw.get('charset', 'utf8'), - autocommit=kw.get('autocommit', True), - maxsize=kw.get('maxsize', 10), - minsize=kw.get('minsize', 1), - loop=loop) + __pool = await aiomysql.create_pool(host=kw.get('host', 'localhost'), + port=kw.get('port', 3306), + user=kw['user'], + password=kw['password'], + db=kw['db'], + charset=kw.get('charset', 'utf8'), + autocommit=kw.get('autocommit', True), + maxsize=kw.get('maxsize', 10), + minsize=kw.get('minsize', 1), + loop=loop) def log(sql, args=()): logging.info('SQL: %s' % sql) -@asyncio.coroutine -def select(sql, args, size=None): +async def select(sql, args, size=None): log(sql, args) - global __pool - with (yield from __pool) as conn: - cur = yield from conn.cursor(aiomysql.DictCursor) - yield from cur.execute(sql.replace('?', '%s'), args or ()) - if size: - rs = yield from cur.fetchmany(size) - else: - rs = yield from cur.fetchall() - yield from cur.close() - logging.info('rows returned %s' % len(rs)) - return rs - - -def execute(sql, args): - log(sql) - with (yield from __pool) as conn: + async with __pool.get() as conn: + # 等待连接对象返回DictCursor可以通过dict的方式获取数据库对象,需要通过游标对象执行SQL + async with conn.cursor(aiomysql.DictCursor) as cur: + await cur.execute( + sql.replace('?', '%s'), + args) #将sql中的'?'替换为'%s',因为mysql语句中的占位符为%s + #如果传入size' + if size: + resultset = await cur.fetchmany(size) # 从数据库获取指定的行数 + else: + resultset = await cur.fetchall() # 返回所有的结果集 + logging.info('rows returned: %s' % len(resultset)) + return resultset + + +async def execute(sql, args, autocommit=True): + log(sql, args) + async with __pool.get() as conn: + if not autocommit: # 若数据库的事务为非自动提交的,则调用协程启动连接 + await conn.begin() try: - cur = yield from conn.cursor() - yield from cur.execute(sql.replace('?', '%s'), args) - affected = cur.rowcount - yield from cur.close() - except Exception as e: - raise + async with conn.cursor( + aiomysql. + DictCursor) as cur: # 打开一个DictCursor,它与普通游标的不同在于,以dict形式返回结果 + await cur.execute(sql.replace('?', '%s'), args) + affected = cur.rowcount # 返回受影响的行数 + if not autocommit: # 同上, 事务非自动提交型的,手动调用协程提交增删改事务 + await conn.commit() + except BaseException as e: + if not autocommit: # 出错, 回滚事务到增删改之前 + await conn.rollback() + raise e return affected @@ -163,7 +169,7 @@ def __getattr__(self, key): try: return self[key] except KeyError: - raise AttributeError(r'Model object has no attribute %s' % key) + raise AttributeError(r"'Model' object has no attribute '%s'" % key) def __setattr__(self, key, value): self[key] = value @@ -184,27 +190,29 @@ def getValueOrDefault(self, key): return value @classmethod - @asyncio.coroutine - def find(cls, pk): + async def find(cls, pk): logging.info('find object by primary key') - rs = yield from select('%s where `%s`=?', - (cls.__select__, cls.__primary_key__), [pk], 1) + rs = await select('%s where `%s`=?' % + (cls.__select__, cls.__primary_key__), [pk], 1) if len(rs) == 0: return None return cls(**rs[0]) - @asyncio.coroutine - def save(self): + @classmethod + async def save(self): args = list(map(self.getValueOrDefault, self.__fields__)) args.append(self.getValueOrDefault(self.__primary_key__)) logging.info(args) - rows = yield from execute(self.__insert__, args) + rows = await execute(self.__insert__, args) if rows != 1: logging.warn('failed to insert record: affected rows: %s' % rows) - @asyncio.coroutine - def findAll(cls, where=None, args=None, **kw): + @classmethod + async def findAll(cls, where=None, args=None, **kw): + ' find objects by where clause. ' sql = [cls.__select__] + # logging.info(cls.__select__) + logging.info(select(' '.join(sql), args)) if where: sql.append('where') sql.append(where) @@ -225,5 +233,5 @@ def findAll(cls, where=None, args=None, **kw): args.extend(limit) else: raise ValueError('Invalid limit value: %s' % str(limit)) - rs = select(' '.join(sql), args) + rs = await select(' '.join(sql), args) return [cls(**r) for r in rs] diff --git a/awesome-python3-webapp/www/templates/test.html b/awesome-python3-webapp/www/templates/test.html index f23da43..939356a 100644 --- a/awesome-python3-webapp/www/templates/test.html +++ b/awesome-python3-webapp/www/templates/test.html @@ -6,9 +6,7 @@ -

All users

{% for u in users %} -

{{ u.name }} / {{ u.email }}

- {% endfor %} +

My name is chenshi2

diff --git a/awesome-python3-webapp/www/test.py b/awesome-python3-webapp/www/test.py index 2702e7f..01d6ce2 100644 --- a/awesome-python3-webapp/www/test.py +++ b/awesome-python3-webapp/www/test.py @@ -2,6 +2,8 @@ import asyncio import sys from models import User, Blog, Comment +import logging +# from confi_default import configs @asyncio.coroutine @@ -10,15 +12,17 @@ def test(loop): user='sa', password='P@ssw0rd', db='awesome') - u = User(name='chenshi2', - email='280580216@qq.com', - passwd='123456', - image='about:blank') - yield from u.save() + # u = User(name='chenshi2', + # email='280580216@qq.com', + # passwd='123456', + # image='about:blank') + # yield from u.save() + # users = User.find('0147201758559317d4ca7b200aa46caa9967cce9ae86107000') + # logging.info(users) + users = yield from User.findAll() + for x in users: + logging.info('name is %s , passwd is %s' % (x.name,x.passwd)) loop = asyncio.get_event_loop() loop.run_until_complete(test(loop)) -loop.close() -if loop.is_closed(): - sys.exit(0)