命名空间/内省:收集sql字符串以进行验证 [英] Namespaces/introspection: collecting sql strings for validation

查看:41
本文介绍了命名空间/内省:收集sql字符串以进行验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想验证sql字符串,它遍布

代码,即我对数据库运行(准备)它们是否很高兴

与陈述。 sql中的拼写错误对于我来说是一个很大的痛苦。


这些陈述不是从较小的部分组装的,但它们将是

不一定在模块级别定义。我可以和班级

级别一起生活,但方法级别最好。而且我绝对不希望
解析源文件,但我愿意标记这些字符串,以便更容易从非sql告诉sql。


所以代码看起来像这样


类Foo:(...):

def aQuery (...):

stmt =""

- checkSql

从双选择1

"""

executeQuery()


在文件的末尾我想写一些像

如果(...):

validateSql()


validateSql()就是问题所在。它将从其他地方进口。

并且必须做一些严肃的魔法。它必须查找其调用者的

模块,找到所有类(和方法,如果我们去那么远)提取

常量,检查是否有任何它们是一个SQL语句并验证

它。


问题是第一部分:如何查找调用者模块和

那里定义的classobjs?或者在

来电者的模块中找到任何常量字符串也可以。或者是否有完全不同的方式来做这样的事情?

解决方案

Martin Drautzburg写道:


我想验证sql字符串,它遍布

代码,即我对数据库运行(准备)它们看看它是否满意

的陈述。 sql中的拼写错误对于我来说是一个很大的痛苦。


这些陈述不是从较小的部分组装的,但它们将是

不一定在模块级别定义。我可以和班级

级别一起生活,但方法级别最好。而且我绝对不希望
解析源文件,但我愿意标记这些字符串,以便更容易从非sql告诉sql。


所以代码看起来像这样


类Foo:(...):

def aQuery (...):

stmt =""

- checkSql

从双选择1

"""

executeQuery()


在文件的末尾我想写一些像

如果(...):

validateSql()


validateSql()就是问题所在。它将从其他地方进口。

并且必须做一些严肃的魔法。它必须查找其调用者的

模块,找到所有类(和方法,如果我们去那么远)提取

常量,检查是否有任何它们是一个SQL语句并验证

它。


问题是第一部分:如何查找调用者模块和

那里定义的classobjs?或者在

来电者的模块中找到任何常量字符串也可以。或者是否有完全不同的方式来做这样的事情?



由于所有字符串都是常量,你可以只标记源代码:


def字符串(文件名):

,打开(文件名,rU)作为插播:
$ d $,表示tokenize.generate_tokens(instream.readline)中的t:

如果t [0 ] == token.STRING:

收益率eval(t [1])


def validateSQL(文件名=无):

如果文件名为无:

#默认在调用模块上运行

filename = sys._getframe(1).f_globals [" __ file __"]

for s in strings(filename):

print" validating",repr(s)


另一种选择是标记SQL语句类似于gettext

将它们包含在函数调用中


sql = SQL(" select * from ...")


然后在调试时将SQL()定义为生产中的无操作或实际的

验证。更简单,更安全的是

总是验证一次:


def SQL(sql,checked = set()):

如果检查了sql:

返回True

如果不是valid_sql(sql):raise ValueError

checked.add(sql)

返回sql


彼得


Peter Otten写道:


Martin Drautzburg写道:


>我想验证sql字符串,它遍布
代码,即我运行(准备)它们针对数据库以查看它是否对语句感到满意。 sql中的拼写错误对我来说是一个很大的痛苦。


>

def validateSQL(filename = None):

如果filename是None:

#默认在调用模块上运行

filename = sys._getframe(1).f_globals [" __ file __"]

表示字符串(文件名):

print" validating",repr(s)



这涉及解析文件。我可以看到它甚至可以在

pyc文件上运行,它确实解决了这个问题。仍然(为了荣耀

的人类思维)我想这样做而不解析文件,但

只是python内存。


另一种选择是将类似于gettext的SQL语句标记为

将它们包含在函数调用中


sql = SQL(select * from ...)


然后将SQL()定义为生产中的无操作或实际的

在调试时验证。更简单,更安全的是

总是验证一次:


def SQL(sql,checked = set()):

如果检查了sql:

返回True

如果不是valid_sql(sql):raise ValueError

checked.add(sql)

返回sql



这不是诀窍。我将无法验证一个sql

语句bofore我跑过使用它的代码片段。或者我会

必须在模块级别定义我所有的sql = SQL内容,不是id。我的意思是,b $ b意思是,问题是:那些sql = SQL语句什么时候真的是

ececuted?


< blockquote> Martin Drautzburg写道:


我想验证sql字符串,它遍布

代码,....这些陈述不会从较小的部分组装,

但它们不会在模块级别定义。我可以

和班级一起生活,....

解析源文件,但是我愿意标记字符串所以它是

更容易从非sql告诉sql。


...还是有完全不同的方式来做这样的事情?



如何使用以下变体:

class _Dummy:pass

OLD_STYLE = type(_Dummy)< br $>
def generate_strings(module):

''''''生成< class< name< valuetriples for a module'''''
$ b dir(模块)中top_level_name的$ b:

top_level_value = getattr(module,top_level_name)

if isinstance(top_level_value,basestring):#strings

yield None,top_level_name,top_level_value

elif isinstance(top_level_value,type):#new-style class

dir中的名字(top_level_value):

value = getattr(top_level_value,name)

if isinstance(value,basestring):

产生top_level_name,名称,值

def sometest(somestring):

''''''你的标准是是一个SQL字符串并且有拼写错误。'''''''

返回len( somestring)20和''

def调查(模块):

表示sys.argv中的modname [1:]:

表示class_,name,generate_strings中的文本(

__import __(modname)):

如果非常出色(文字):

如果class_为None:

print''看看%s'的顶级字符串%s。''% (

modname,name)

else:

print"看看%s,类%s,字符串%s。''%

modname,class_,name)

if __name__ ==''__ main__'':

import sys

对于sys.argv中的modname [1:]:

调查(modname,sometest)


-

--Scott David Daniels
sc *********** @ acm.org


I would like to validate sql strings, which are spread all over the
code, i.e. I run ("prepare") them against a database to see if it happy
with the statements. Spelling errors in sql have been a major pain for
me.

The statements will not be assembled from smaller pieces, but they will
not neccessarily be defined at module level. I could live with class
level, but method level would be best. And I definitely don''t want to
parse the source file, but I am willing to mark the strings so it is
easier to tell sql from non-sql.

So the code will look like this

class Foo:(...):
def aQuery(...):
stmt = """
-- checkSql
select 1 from dual
"""
executeQuery()

at the end of the file I would like to write something like
if (...):
validateSql()

The validateSql() is the problem. It would be imported from elsewhere.
and has to do some serious magic. It would have to lookup its caller''s
module, find all the classes (and methods, if we go that far) extract
the constants, check if any of them are an SQL statement and validate
it.

The problem is the first part: how can I lookup the callers module and
the classobjs defined in there? Or finding any constant strings in the
caller''s module would also be just fine. Or is there a completely
different way to do such a thing?

解决方案

Martin Drautzburg wrote:

I would like to validate sql strings, which are spread all over the
code, i.e. I run ("prepare") them against a database to see if it happy
with the statements. Spelling errors in sql have been a major pain for
me.

The statements will not be assembled from smaller pieces, but they will
not neccessarily be defined at module level. I could live with class
level, but method level would be best. And I definitely don''t want to
parse the source file, but I am willing to mark the strings so it is
easier to tell sql from non-sql.

So the code will look like this

class Foo:(...):
def aQuery(...):
stmt = """
-- checkSql
select 1 from dual
"""
executeQuery()

at the end of the file I would like to write something like
if (...):
validateSql()

The validateSql() is the problem. It would be imported from elsewhere.
and has to do some serious magic. It would have to lookup its caller''s
module, find all the classes (and methods, if we go that far) extract
the constants, check if any of them are an SQL statement and validate
it.

The problem is the first part: how can I lookup the callers module and
the classobjs defined in there? Or finding any constant strings in the
caller''s module would also be just fine. Or is there a completely
different way to do such a thing?

Since all strings are constants you could just tokenize the source code:

def strings(filename):
with open(filename, "rU") as instream:
for t in tokenize.generate_tokens(instream.readline):
if t[0] == token.STRING:
yield eval(t[1])

def validateSQL(filename=None):
if filename is None:
# by default operate on the calling module
filename = sys._getframe(1).f_globals["__file__"]
for s in strings(filename):
print "validating", repr(s)

Another option would be to mark SQL statements similar to gettext by
enclosing them in a function call

sql = SQL("select * from...")

and then defining SQL() as either a no-op in production or an actual
validation while you are debugging. Even simpler and safer would be to
always validate once:

def SQL(sql, checked=set()):
if sql in checked:
return True
if not valid_sql(sql): raise ValueError
checked.add(sql)
return sql

Peter


Peter Otten wrote:

Martin Drautzburg wrote:

>I would like to validate sql strings, which are spread all over the
code, i.e. I run ("prepare") them against a database to see if it
happy with the statements. Spelling errors in sql have been a major
pain for me.

>
def validateSQL(filename=None):
if filename is None:
# by default operate on the calling module
filename = sys._getframe(1).f_globals["__file__"]
for s in strings(filename):
print "validating", repr(s)

This involves parsing the file. I can see that it would even work on a
pyc file and it actually does solve the problem. Still (for the glory
of the human mind) I would like to do this without parsing a file, but
just the python internal memory.

Another option would be to mark SQL statements similar to gettext by
enclosing them in a function call

sql = SQL("select * from...")

and then defining SQL() as either a no-op in production or an actual
validation while you are debugging. Even simpler and safer would be to
always validate once:

def SQL(sql, checked=set()):
if sql in checked:
return True
if not valid_sql(sql): raise ValueError
checked.add(sql)
return sql

No this does not do the trick. I will not be able to validate an sql
statement bofore I run over the piece of code that uses it. Or I would
have to define all my sql = SQL stuff on module level, isn''t id. I
mean, the problem is: when are those sql = SQL statement really
ececuted?


Martin Drautzburg wrote:

I would like to validate sql strings, which are spread all over the
code, .... The statements will not be assembled from smaller pieces,
but they will not neccessarily be defined at module level. I could
live with class level, ....
parse the source file, but I am willing to mark the strings so it is
easier to tell sql from non-sql.

... Or is there a completely different way to do such a thing?

How about using some variation of:
class _Dummy: pass
OLD_STYLE = type(_Dummy)
def generate_strings(module):
''''''Generate <class<name<valuetriples for a module''''''
for top_level_name in dir(module):
top_level_value = getattr(module, top_level_name)
if isinstance(top_level_value, basestring): # strings
yield None, top_level_name, top_level_value
elif isinstance(top_level_value, type): # new-style class
for name in dir(top_level_value):
value = getattr(top_level_value, name)
if isinstance(value, basestring):
yield top_level_name, name, value
def sometest(somestring):
''''''Your criteria for "is an SQL string and has misspellings".''''''
return len(somestring) 20 and ''
def investigate(module):
for modname in sys.argv[1:]:
for class_, name, text in generate_strings(
__import__(modname)):
if remarkable(text):
if class_ is None:
print ''Look at %s''s top-level string %s.'' % (
modname, name)
else:
print "Look at %s, class %s, string %s.'' %
modname, class_, name)
if __name__ == ''__main__'':
import sys
for modname in sys.argv[1: ]:
investigate(modname, sometest)

--
--Scott David Daniels
sc***********@acm.org


这篇关于命名空间/内省:收集sql字符串以进行验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆