473,387 Members | 1,553 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Namespaces/introspection: collecting sql strings for validation

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?
Apr 22 '07 #1
12 1305
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
Apr 22 '07 #2
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?

Apr 22 '07 #3
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
Apr 22 '07 #4
On Apr 21, 4:16 pm, Martin Drautzburg <Martin.Drautzb...@web.de>
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?
Yes, there is: use an ORM to do the SQL generation for you. Check out
SQLAlchemy, it will buy you much more than what you asked for.

George

Apr 22 '07 #5
Martin Drautzburg <Ma***************@web.dewrote:
...
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?
Don't do black magic in production code.

For just hacking around, see sys._getframe -- it can give you a frame
object from where you can introspect into your caller's globals -- and
the inspect module of the standard Python library.

But don't put such black magic in production. The completely different
way is: just don't.
Alex
Apr 23 '07 #6
Martin Drautzburg wrote:
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?
Let's see:
>>def SQL(sql):
.... print sql
....
>>a = SQL("module")
module # that one was obvious
>>class A:
.... b = SQL("class")
.... def method(self, c=SQL("default arg")):
.... d = SQL("method")
....
class # ha, class statements are executed, too...
default arg # ...as are default arguments

Peter
Apr 23 '07 #7
George Sakkis wrote:
Yes, there is: use an ORM to do the SQL generation for you. Check out
SQLAlchemy, it will buy you much more than what you asked for.
Might look, though in general I don't like OR mappers much. Having SQL
generated feels as strange as having python code generated. Too much
magic, too many layers. I think it is better to simply learn SQL.

And I don't really believe in OO databases much. OO databases have been
around for several decades and still have not reached the maturity of
relational databases. My feeling is that OO and persistence to not play
together well.

Apr 23 '07 #8
Peter Otten wrote:
>>>def SQL(sql):
... * * print sql
...
>>>a = SQL("module")
module # that one was obvious
>>>class A:
... * * b = SQL("class")
... * * def method(self, c=SQL("default arg")):
... * * * * * * d = SQL("method")
...
You are my hero. Indeed very cool!
Apr 23 '07 #9
In article <1h***************************@mac.com>,
Alex Martelli <al***@mac.comwrote:
>Martin Drautzburg <Ma***************@web.dewrote:
>>
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?

Don't do black magic in production code.

For just hacking around, see sys._getframe -- it can give you a frame
object from where you can introspect into your caller's globals -- and
the inspect module of the standard Python library.

But don't put such black magic in production. The completely different
way is: just don't.
Could you expand on that? After all, that's exactly what we do to
implement a super() that works with classic classes -- and it's certainly
production code.
--
Aahz (aa**@pythoncraft.com) <* http://www.pythoncraft.com/

"...string iteration isn't about treating strings as sequences of strings,
it's about treating strings as sequences of characters. The fact that
characters are also strings is the reason we have problems, but characters
are strings for other good reasons." --Aahz
Apr 23 '07 #10
Aahz <aa**@pythoncraft.comwrote:
But don't put such black magic in production. The completely different
way is: just don't.

Could you expand on that? After all, that's exactly what we do to
implement a super() that works with classic classes -- and it's certainly
production code.
Personally, I'd much rather give up super (not a big loss) and classic
classes (a substantial net gain:-) than have to maintain such "black
magic" in a production environment. Explicit is better than implicit,
&c.
Alex
Apr 24 '07 #11
Martin Drautzburg <Ma***************@web.dewrote:
George Sakkis wrote:
Yes, there is: use an ORM to do the SQL generation for you. Check out
SQLAlchemy, it will buy you much more than what you asked for.

Might look, though in general I don't like OR mappers much. Having SQL
generated feels as strange as having python code generated. Too much
magic, too many layers. I think it is better to simply learn SQL.
Amen, brother; this opinion is definitely an outdated and minority one,
today, but I do tend to share it (and yet I'm programming in Django a
lot these days... ah well, consistency, hobgoblin, little minds, &c:-).
Alex
Apr 24 '07 #12
In article <1h**************************@mac.com>,
Alex Martelli <al***@mac.comwrote:
>Aahz <aa**@pythoncraft.comwrote:
>>Alex:
>>>
But don't put such black magic in production. The completely different
way is: just don't.

Could you expand on that? After all, that's exactly what we do to
implement a super() that works with classic classes -- and it's certainly
production code.

Personally, I'd much rather give up super (not a big loss) and classic
classes (a substantial net gain:-) than have to maintain such "black
magic" in a production environment. Explicit is better than implicit,
&c.
This application was started with Python 1.4. We still use Python 2.2,
which has some subtle but critical differences with the way new-style
classes are handled in 2.3+. Using super() makes our plugin model work;
otherwise, we'd have to switch to a non-cooperative mechanism for calling
plugin hooks. That would have some advantages, of course, but so much
code would need rewriting, and managing the calling of plugin hooks would
require creating an API registry.

The world is not always a simple place....
--
Aahz (aa**@pythoncraft.com) <* http://www.pythoncraft.com/

"...string iteration isn't about treating strings as sequences of strings,
it's about treating strings as sequences of characters. The fact that
characters are also strings is the reason we have problems, but characters
are strings for other good reasons." --Aahz
Apr 25 '07 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Zombie | last post by:
Hi, Can I have 2 namespaces in the same XML schema? In the schema, I wish to declare elements such that some of them belong to one namespace and others belong to a second namespace. Is this...
81
by: sinister | last post by:
I wanted to spiff up my overly spartan homepage, and started using some CSS templates I found on a couple of weblogs. It looks fine in my browser (IE 6.0), but it doesn't print right. I tested...
0
by: Steven T. Hatton | last post by:
I suspect the core language is not the level at which introspection should be implemented in C++. That has been the choice of C#, and Java. Both of these languages made some trade-offs to...
4
by: Steven T. Hatton | last post by:
Has there been any substantial progress toward supporting introspection/reflection in C++? I don't intend to mean it should be part of the Standard. It would, nonetheless, be nice to have a...
1
by: Dan Bass | last post by:
There's an XML message I have, that has no namespace information. Then there is a XSD schema that is must validate against, but this has a targetNamespace and xmlns of...
36
by: Wilfredo Sánchez Vega | last post by:
I'm having some issues around namespace handling with XML: >>> document = xml.dom.minidom.Document() >>> element = document.createElementNS("DAV:", "href") >>> document.appendChild(element)...
8
by: Florian Daniel Otel | last post by:
Hello all, As the subject says, I am a newcomer to Python and I have a newcomer question wrt namespaces and variable scope. Obviously, I might be missing smth obvious, so TIA for the patience...
14
by: Dave Rahardja | last post by:
Is there a way to generate a series of statements based on the data members of a structure at compile time? I have a function that reverses the endianness of any data structure: /// Reverse...
4
by: noosaj | last post by:
Hello, I use vs2005 and I'm a college student studying programming. I'm currently enrolled in a visual basic programming class. I have one question, and I apologize if it sounds dumb. What...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.