2015年2月1日星期日

将Json数据转换为ADO.NET DataSet对象 - dax.net

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
将Json数据转换为ADO.NET DataSet对象 - dax.net  阅读原文»

Json数据转换为ADO.NET DataSet其实方法有很多,Newtonsoft.Json也提供了DataSet的Converter用以转换Json数据。但是有些情况下DataSet Converter并不管用,而且也不一定能够满足项目需要。这里介绍另一种简单有效的方法,能够方便快速地将Json数据转为ADO.NET DataSet。

设计

事实上Newtonsoft.Json已经提供了一套完整的Json数据文档结构,Newtonsoft.Json.Linq命名空间下提供了这种文档结构的对象模型,因此我们可以借用这样的模型,在其上应用访问者(Visitor,GoF95)模式,对树状结构的对象模型进行遍历,以达到ADO.NET DataTable、DataRelation的创建以及DataSet的生成。基本对象模型如下:

2015-02-01 21_43_47-Json2DataSet - Microsoft Visual Studio

其实实现起来还是非常简单的,我已经把完整的项目和单元测试开源到GitHub上。具体的代码可以参考https://github.com/daxnet/Json2DataSet开源项目。

性能

性能方面,在实现的过程中,我发现有两个地方是性能瓶颈:

  1. 正则表达式
  2. JToken.Path属性

如果在你的代码中需要高频率地反复调用这两种操作,那么你就需要考虑性能问题。尤其是JToken.Path属性,它的内部实现牵涉到链表数据结构、复杂循环等,因此效率不是很高,应该尽量避免使用这一属性(当然我开源的代码中还有一处在调用该属性,可以进一步优化)。

另一方面,对于ADO.NET DataTable和DataRelation的构建,性能还是相当高的,无需担心。总体上看,将15MB的Json数据转换为DataSet仅需4秒左右,有兴趣的朋友还可以在该代码基础上进一步优化。

调用

在该开源项目主页上已经说明了调用方式。很简单:

var json = File.ReadAllText(@"d:\test.json");
var dataSet = Json2DataSetConverter.Convert(json);

比如通过调用某个RESTful API,获得Json Response以后,直接将返回结果转换为DataSet,并在Visual Studio Debug Visualizer for DataSet中看到某公司的客户信息,以及这些客户所完成的订单数据:

image

应用

TIBCO Spotfire是一种世界先进的数据分析软件,不仅功能强大,还可以为其定制数据导入插件,方便地将外部数据导入其中进行分析。它是以表的形式对数据进行整合和分析的,因此,它对ADO.NET DataSet的支持是非常好的,能够很方便地将ADO.NET DataSet中所包含的表数据导入。

现有一个RESTful API,它能够获取全世界所有国家的列表信息,包括国家名称、语言、人口、与该国接壤的国家数量等等。该API的地址是:

GET http://restcountries.eu/rest/v1/all

好了,现在我开发了一个非常简单的插件,可以通过GET命令,从RESTful API导入数据到TIBCO Spotfire中:

image

导入数据后,我可以立刻分析出哪个国家人口比重最大,哪个国家与其接壤的国家数量最多:

image

看,我国不仅人口最多(占世界人口的19%),而且与我国接壤的国家数量最多(15个)。


本文链接:将Json数据转换为ADO.NET DataSet对象,转载请注明。

Flask学习之五 用户登录 - AminHuang  阅读原文»

英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins

中文翻译地址:http://www.pythondoc.com/flask-mega-tutorial/userlogin.html

开源中国社区:http://www.oschina.net/translate/the-flask-mega-tutorial-part-v-user-logins

备注:我是三个一起看的,有些部分的中文翻译太拗口而且还有错,因此我选择是比较清晰的中文解释,而有些部分是直接翻译英文博客。

上一部分:Flask学习之四 数据库

一、配置

对于登录系统,我们将会使用到两个扩展,Flask-Login 和 Flask-OpenID。配置情况如下(文件 app__init__.py):

import os
from flask.ext.login import LoginManager
from flask.ext.openid import OpenID
from config import basedir

lm
= LoginManager()
lm.init_app(app)
oid
= OpenID(app, os.path.join(basedir, 'tmp'))

Flask-OpenID 扩展需要一个存储文件的临时文件夹的路径。对此,我们提供了一个 tmp 文件夹的路径。

二、重构用户模型

Flask-Login扩展需要在我们的User类里实现一些方法。

为 Flask-Login 实现的 User 类(文件 app/models.py):

class User(db.Model):
id
= db.Column(db.Integer, primary_key = True)
nickname
= db.Column(db.String(64), unique = True)
email
= db.Column(db.String(120), unique = True)
role
= db.Column(db.SmallInteger, default = ROLE_USER)
posts
= db.relationship('Post', backref = 'author', lazy = 'dynamic')

def is_authenticated(self):
return True

def is_active(self):
return True

def is_anonymous(self):
return False

def get_id(self):
return unicode(self.id)

def __repr__(self):
return '<User %r>' % (self.nickname)

is_authenticated 方法:一般而言,这个方法应该只返回 True,除非表示用户的对象因为某些原因不允许被认证。

is_active 方法:应该返回 True,除非用户是无效的,比如他们的账号被禁止。

is_anonymous方法:为那些不被获准登录的用户返回True。

get_id方法:为用户返回唯一的unicode标识符。我们用数据库层生成唯一的id。

三、User loader 回调

现在我们通过使用Flask-Login和Flask-OpenID扩展来实现登录系统

首先,我们需要写一个方法从数据库加载到一个用户。这个方法会被Flask-Login使用(文件 app/views.py):

@lm.user_loader
def load_user(id):
return User.query.get(int(id))

备注:其实我现在对python中的@符号的用法还是不甚明了。

注意在 Flask-Login 中的用户 ids 永远是 unicode 字符串,因此在我们把 id 发送给 Flask-SQLAlchemy 之前,需要把 id 转成整型,否则会报错!

四、登录视图函数

接着更新登录视图函数(文件 app/views.py):

from flask import render_template, flash, redirect, session, url_for, request, g
from flask.ext.login import login_user, logout_user, current_user, login_required
from app import app, db, lm, oid
from forms import LoginForm
from models import User

@app.route(
'/login', methods=['GET', 'POST'])
@oid.loginhandler
def login():
if g.user is not None and g.user.is_authenticated():
return redirect(url_for('index'))
form
= LoginForm()
if form.validate_on_submit():
session[
'remember_me'] = form.remember_me.data
return oid.try_login(form.openid.data, ask_for=['nickname', 'email'])
return render_template('login.html',
title
='Sign In',
form
=form,
providers
=app.config['OPENID_PROVIDERS'])

注意上面导入了很多新模块,之后会用到。

视图函数添加了一个新的装饰器:oid.loginhandler。它告诉Flask-OpenID这是我们的登录视图函数。

在函数开始的时候我们就检查 g.user 是不是一个已经认证的用户,如果已经认证就直接跳转到主页面,避免二次登录。

Flask 中的 g 全局变量是一个在请求生命周期中用来存储和共享数据。登录的用户存储在这里(g)。

我们在调用redirect()时使用的url_for()方法是Flask定义的从给定的view方法获取url。如果你想重定向到index页面,你很可能使用redirect('/index'),但是让Flask为你构造url是有好处的。见 http://dormousehole.readthedocs.org/en/latest/quickstart.html#url

当我们从登录表单得到返回数据,接下来要运行的代码也是新写的。这儿我们做两件事。首先我们保存remember_me的布尔值到Flask的 session中,别和Flask-SQLAlchemy的db.session混淆了。之前我们已经知道 flask.g 对象在请求整个生命周期中存储和共享数据。flask.session 提供了一个更加复杂的服务对于存储和共享数据。一旦数据存储在会话对象中,在来自同一客户端的现在和任何以后的请求都是可用的。数据将保持在session中直到被明确的移除。为了做到这些,Flask为每个客户端建立各自的 session。

oid.try_login通过Flask-OpenID来执行用户认证。该函数有两个参数,用户在 web 表单提供的 openid 以及我们从 OpenID 提供商得到的数据项列表。因为我们已经在用户模型类中定义了 nicknameemail,这也是我们将要从 OpenID 提供商索取的。

基于OpenID的认证是异步的。如果认证成功,Flask-OpenID将调用有由oid.after_login装饰器注册的方法。如果认证失败那么用户会被重?p>阅读更多内容

没有评论:

发表评论