[Zope-dev] Using db_connections from Zope products
Kent Polk
kent@goathill.org
26 Jun 2001 18:30:02 GMT
On 20 Jun 2001 11:25:01 -0500, Tom Brown wrote:
> I would like to make an SQL query directly from python
> code. Do I have to make a
> ZSQL Method dynamically, or is there another way
> without making the class database
> dependent (i.e. Gadfly, PoPy, etc), utilizing an
> existing db_con? Suppose I am using the ZPoPy DA and
> have established a database connection externally.
> How can I access this database
> and submit a query from my own class?
I have a product which queries a specified database table from the
Product Class and both executes queries entirely in Python, and
builds ZSQL methods - populating them with std queries that can
then be customized.
You can directly use the database connection_id, but you will
probably want to insert :
import pdb; pdb.set_trace()
in your class and use the debugger as you go.
(I'll throw some probably bad code at you here - caveat emptor)
To start out, somewhere you will want to be able to specify the
connection id to use, such as:
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<EM><STRONG>Connection Id</STRONG></EM>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<SELECT NAME="connection_id">
<dtml-in SQLConnectionIDs>
<OPTION VALUE="&dtml-sequence-item;">
<dtml-var sequence-key></OPTION>
</dtml-in>
</SELECT>
</TD>
</TR>
and in your class, somewhere, something like this:
if REQUEST and REQUEST.has_key('connection_id'):
self.connection_id = REQUEST['connection_id']
To create the zsql methods, I first have to obtain some info:
def dbquery_handle(obj, connection_id):
"""Find and return the Zope database connector query method """
database_type = ''
# Locate the Database Connector
try:
dbc=getattr(obj, connection_id)
database_type = dbc.database_type
except AttributeError:
raise AttributeError, (
"The database connection <em>%s</em> cannot be found." %
(connection_id))
# Prepare the Database Connector for a query
try: DB__=dbc()
except: raise 'Database Error', (
'%s is not connected to a database' % connection_id)
# Return the query method
return database_type, DB__.query
# There's got to be a more universal way to do this, but I don't
# know what it is
def tableexists(dbtype, dbq, tablename):
"""Query the database to see if the table exists"""
table_exists = []
if dbtype == 'MySQL':
try:
table_show_query = 'SHOW TABLES LIKE "%s"'
meta, table_exists = dbq(table_show_query % tablename, 1)
return table_exists
except :
pass
elif dbtype == 'Sybase':
try:
table_show_query = "SELECT name FROM sysobjects \
WHERE id = object_id('%s')"
meta, table_exists = dbq(table_show_query % tablename, 1)
return table_exists
except:
pass
return table_exists
Now..
# ZSQL Method creation
def create_zsqlmethods(self, id, connection_id, properties, maketable=0):
"""Create a series of Zope SQLMethods for this table """
schema = []
tableschema = []
dbtype, dbquery = dbquery_handle(self, connection_id)
table_exists = tableexists(dbtype, dbquery, id)
... determine table schema from whatever, and instantiate the 'create'
SQL method:
create = SQL('createTable', title='',
connection_id=connection_id, arguments='',
template=table_create_query %(id, vars))
self._setObject('createTable', create)
...
and even create the SQL table if you need to:
if not table_exists and maketable:
self.createTable()
etc. etc.