Mercurial > hg > ChinaGisRestApi
changeset 16:cbb73d103152
NEW - # 12: create table and upload data
https://it-dev.mpiwg-berlin.mpg.de/tracs/GIS/ticket/12
works now!
author | casties |
---|---|
date | Mon, 16 Aug 2010 21:24:00 +0200 |
parents | 5e3edf980813 |
children | ed997e639cfd |
files | RestDbInterface.py |
diffstat | 1 files changed, 64 insertions(+), 75 deletions(-) [+] |
line wrap: on
line diff
--- a/RestDbInterface.py Mon Aug 16 12:13:36 2010 +0200 +++ b/RestDbInterface.py Mon Aug 16 21:24:00 2010 +0200 @@ -9,6 +9,7 @@ from Products.ZSQLExtend import ZSQLExtend import logging import re +import psycopg2 from zope.interface import implements from zope.publisher.interfaces import IPublishTraverse @@ -20,26 +21,29 @@ from Products.ZSQLMethods.SQL import SQLConnectionIDs -def getTextFromNode(nodename): +def getTextFromNode(node): """get the cdata content of a XML node""" - if nodename is None: + if node is None: return "" - nodelist=nodename.childNodes + + if isinstance(node, list): + nodelist = node + else: + nodelist=node.childNodes + rc = "" for node in nodelist: if node.nodeType == node.TEXT_NODE: rc = rc + node.data return rc -def sqlName(s,lc=False): - """returns ASCII-only version of string""" +def sqlName(s,lc=True): + """returns restricted ASCII-only version of string""" if s is None: return "" - # blank -> "-" - s = re.sub(r' ','-',s) # all else -> "_" - s = re.sub(r'[^A-Za-z0-9_-]','_',s) + s = re.sub(r'[^A-Za-z0-9_]','_',s) if lc: return s.lower() @@ -105,11 +109,13 @@ raise IOError("No database connection! (%s)"%str(e)) cursor = conn.getcursor() + cursor.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) return cursor def executeSQL(self, query, *args): """execute query with args on database and return all results. result format: {"fields":fields, "rows":data}""" + logging.debug("executeSQL query=%s args=%s"%(query,args)) cur = self.getCursor() cur.execute(query, args) # description of returned fields @@ -119,6 +125,15 @@ cur.close() return {"fields":fields, "rows":data} + def executeOnlySQL(self, query, *args): + """execute query with args on database that has no results. + result format: {"fields":fields, "rows":data}""" + logging.debug("executeOnlySQL query=%s args=%s"%(query,args)) + cur = self.getCursor() + cur.execute(query, args) + cur.close() + return None + def publishTraverse(self,request,name): """change the traversal""" @@ -222,7 +237,7 @@ def getTable(self,schema='public',table=None,username='guest'): """return table data""" logging.debug("gettable") - data = self.executeSQL("select * from %s"%table) + data = self.executeSQL('select * from "%s"."%s"'%(schema,table)) return data def showListOfTables(self,format='XML',schema='public'): @@ -284,15 +299,16 @@ # drop table if it exists try: - res = executeSQL('drop table "%s.%s"'%(schema,table)) - logging.debug("createemptytable: dropped table %s.%s"%(schema,table)) + res = self.executeSQL('select * from "%s"."%s" where 1=0'%(schema,table)) + logging.debug("createemptytable: table %s.%s exists"%(schema,table)) + self.executeOnlySQL('drop table "%s"."%s"'%(schema,table)) except: pass fieldString = ", ".join(['"%s" %s'%(f['name'],f['type']) for f in sqlFields]) - sqlString = 'create table "%s.%s" (%s)'%(schema,table,fieldString) - loging.debug("createemptytable: SQL=%s"%sqlString) - ret = self.executeSQL(sqlString) + sqlString = 'create table "%s"."%s" (%s)'%(schema,table,fieldString) + logging.debug("createemptytable: SQL=%s"%sqlString) + ret = self.executeOnlySQL(sqlString) return sqlFields @@ -303,7 +319,7 @@ logging.debug("createTableFromXML schema=%s table=%s data=%s"%(schema,table,data)) self.importExcelXML(schema,table, data) - def importExcelXML(self,schema,table,data,fieldNamesOnly=False): + def importExcelXML(self,schema,table,xmldata,fieldNamesOnly=False): ''' Import XML file in Excel format into the table @param table: name of the table the xml shall be imported into @@ -317,20 +333,22 @@ namespace = "urn:schemas-microsoft-com:office:spreadsheet" containerTagName = "Table" rowTagName = "Row" + colTagName = "Cell" dataTagName = "Data" fieldNames = [] sqlFields = [] + numFields = 0 sqlInsert = None logging.debug("import excel xml") ret="" - if isinstance(data, str): + if isinstance(xmldata, str): logging.debug("importXML reading string data") - doc=parseString(data) + doc=parseString(xmldata) else: logging.debug("importXML reading file data") - doc=parse(data) + doc=parse(xmldata) cnt = 0 while True: @@ -340,17 +358,13 @@ break else: + #logging.debug("tag=%s"%node[1].localName) if node[1].localName is not None: tagName = node[1].localName.lower() else: # ignore non-tag nodes continue - - if tagName == containerTagName.lower(): # make everything case insensitive - # start of container -- do we need this? - cnt = 0 - continue - + if tagName == rowTagName.lower(): # start of row doc.expandNode(node[1]) @@ -368,67 +382,42 @@ # create table sqlFields = self.createEmptyTable(schema, table, fieldNames) + numFields = len(sqlFields) fieldString = ", ".join(['"%s"'%f['name'] for f in sqlFields]) valString = ", ".join(["%s" for f in sqlFields]) - sqlInsert = 'insert into "%s.%s" (%s) values (%s)'%(schema,table,fieldString,valString) + sqlInsert = 'insert into "%s"."%s" (%s) values (%s)'%(schema,table,fieldString,valString) logging.debug("importexcelsql: sqlInsert=%s"%sqlInsert) else: # following rows are data - dataNodes=node[1].getElementsByTagNameNS(namespace, dataTagName) + colNodes=node[1].getElementsByTagNameNS(namespace, colTagName) data = [] - for dataNode in dataNodes: - val = getTextFromNode(dataNodes) + hasData = False + for colNode in colNodes: + dataNodes=colNode.getElementsByTagNameNS(namespace, dataTagName) + if len(dataNodes) > 0: + val = getTextFromNode(dataNodes[0]) + hasData = True + else: + val = None + data.append(val) - self.executeSQL(sqlInsert, data) - - - continue - - '''dataSet={} - for col in node[1].childNodes: - if col.nodeType is col.ELEMENT_NODE: - data=col.nodeName - dataSet[data]=getTextFromNode(col) - - update=False - - if identify: - - field=dataSet[identify] - - searchStr="""select %s from %s where %s = '%s'"""%(identify,table,identify,field) - logger("import xml",logging.INFO,searchStr) - search=self.ZSQLSimpleSearch(searchStr) - if search: - update=True - - if update: - tmp=[] - for fieldName in dataSet.keys(): - tmp.append("""%s = %s"""%(fieldName,self.ZSQLQuote(dataSet[fieldName]))) - setStr=",".join(tmp) - - field=dataSet[identify] - - queryStr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,identify,field) - logger("update xml",logging.INFO,queryStr) - self.ZSQLSimpleSearch(queryStr) - ret+="ud: %s \n"%field - - else: - fields=",".join(dataSet.keys()) - values=",".join([""" %s """%self.ZSQLQuote(dataSet[x]) for x in dataSet.keys()]) - - - queryStr="""INSERT INTO %s (%s) VALUES (%s)"""%(table,fields,values) - self.ZSQLSimpleSearch(queryStr) - logger("update xml",logging.INFO,queryStr) - ''' + if not hasData: + # ignore empty rows + continue + + # fix number of data fields + if len(data) > numFields: + del data[numFields:] + elif len(data) < numFields: + missFields = numFields - len(data) + data.extend(missFields * [None,]) + + logging.debug("importexcel sqlinsert=%s data=%s"%(sqlInsert,data)) + self.executeOnlySQL(sqlInsert, *data) - logging.debug("XML import field names: %s"%(fieldNames)) - return ret + return cnt def manage_editRestDbInterface(self, title=None, connection_id=None,