--- ZSQLExtend/importFMPXML.py 2007/03/29 18:31:32 1.8 +++ ZSQLExtend/importFMPXML.py 2007/04/02 09:48:13 1.9 @@ -85,10 +85,8 @@ class TableColumn: class xml_handler: - def __init__(self,options): - ''' - SAX handler to import FileMaker XML file (FMPXMLRESULT format) into the table. + """SAX handler to import FileMaker XML file (FMPXMLRESULT format) into the table. @param options: dict of options @param options.dsn: database connection string @param options.table: name of the table the xml shall be imported into @@ -100,7 +98,8 @@ class xml_handler: @param options.keep_fields: (optional) don't add fields to SQL database @param options.ascii_db: (optional) assume ascii encoding in db @param options.replace_table: (optional) delete and re-insert data - ''' + """ + # set up parser self.event = None self.top_dispatcher = { @@ -115,17 +114,17 @@ class xml_handler: self.db = self.dbCon.cursor() assert self.db, "AIIEE no db cursor for %s!!"%options.dsn - self.table = options.table - self.update_fields = options.update_fields - self.id_field = options.id_field - self.sync_mode = options.sync_mode - self.lc_names = options.lc_names - self.keep_fields = options.keep_fields - self.ascii_db = options.ascii_db - self.replace_table = options.replace_table - self.backup_table = options.backup_table + self.table = getattr(options,"table",None) + self.update_fields = getattr(options,"update_fields",None) + self.id_field = getattr(options,"id_field",None) + self.sync_mode = getattr(options,"sync_mode",None) + self.lc_names = getattr(options,"lc_names",None) + self.keep_fields = getattr(options,"keep_fields",None) + self.ascii_db = getattr(options,"ascii_db",None) + self.replace_table = getattr(options,"replace_table",None) + self.backup_table = getattr(options,"backup_table",None) - logging.debug("dsn: "+repr(options.dsn)) + logging.debug("dsn: "+repr(getattr(options,"dsn",None))) logging.debug("table: "+repr(self.table)) logging.debug("update_fields: "+repr(self.update_fields)) logging.debug("id_field: "+repr(self.id_field)) @@ -233,6 +232,7 @@ class xml_handler: # update existing fields self.update_fields = self.sql_fields + else: # update all fields if self.lc_names: @@ -453,89 +453,102 @@ class xml_handler: -## -## public static int main() -## - -from optparse import OptionParser - -opars = OptionParser() -opars.add_option("-f", "--file", - dest="filename", - help="FMPXML file name", metavar="FILE") -opars.add_option("-c", "--dsn", - dest="dsn", - help="database connection string") -opars.add_option("-t", "--table", - dest="table", - help="database table name") -opars.add_option("--fields", default=None, - dest="update_fields", - help="list of fields to update (comma separated, sql-names)", metavar="LIST") -opars.add_option("--id-field", default=None, - dest="id_field", - help="name of id field for synchronisation (only appends data otherwise, sql-name)", metavar="NAME") -opars.add_option("--sync", "--sync-mode", default=False, action="store_true", - dest="sync_mode", - help="do full sync based on id field (remove unmatched fields from db)") -opars.add_option("--lc-names", default=False, action="store_true", - dest="lc_names", - help="clean and lower case field names from XML") -opars.add_option("--keep-fields", default=False, action="store_true", - dest="keep_fields", - help="don't add fields from XML to SQL table") -opars.add_option("--ascii-db", default=False, action="store_true", - dest="ascii_db", - help="the SQL database stores ASCII instead of unicode") -opars.add_option("--replace", default=False, action="store_true", - dest="replace_table", - help="replace table i.e. delete and re-insert data") -opars.add_option("--backup", default=False, action="store_true", - dest="backup_table", - help="create backup of old table (breaks indices)") -opars.add_option("-d", "--debug", default=False, action="store_true", - dest="debug", - help="debug mode (more output)") - -(options, args) = opars.parse_args() - -if len(sys.argv) < 2 or options.filename is None or options.dsn is None: - print "importFMPXML "+version_string - opars.print_help() - sys.exit(1) - -if options.debug: - loglevel = logging.DEBUG -else: - loglevel = logging.INFO - -logging.basicConfig(level=loglevel, - format='%(asctime)s %(levelname)s %(message)s', - datefmt='%H:%M:%S') - -update_fields = None - -if options.update_fields: - uf = {} - for f in options.update_fields.split(','): - (n,t) = f.split(':') - uf[n] = TableColumn(n,t) - - options.update_fields = uf - -if options.id_field and options.replace_table: - logging.error("ABORT: sorry, you can't do both sync (id_field) and replace") - sys.exit(1) - -parser = sax.make_parser() -#The "consumer" is our own handler -consumer = xml_handler(options) -#Initialize Tenorsax with handler -handler = saxtools.tenorsax(consumer) -#Resulting tenorsax instance is the SAX handler -parser.setContentHandler(handler) -parser.setFeature(sax.handler.feature_namespaces, 1) -parser.parse(options.filename) +if __name__ == "__main__": + from optparse import OptionParser + opars = OptionParser() + opars.add_option("-f", "--file", + dest="filename", + help="FMPXML file name", metavar="FILE") + opars.add_option("-c", "--dsn", + dest="dsn", + help="database connection string") + opars.add_option("-t", "--table", + dest="table", + help="database table name") + opars.add_option("--fields", default=None, + dest="update_fields", + help="list of fields to update (comma separated, sql-names)", metavar="LIST") + opars.add_option("--id-field", default=None, + dest="id_field", + help="name of id field for synchronisation (only appends data otherwise, sql-name)", metavar="NAME") + opars.add_option("--sync", "--sync-mode", default=False, action="store_true", + dest="sync_mode", + help="do full sync based on id field (remove unmatched fields from db)") + opars.add_option("--lc-names", default=False, action="store_true", + dest="lc_names", + help="clean and lower case field names from XML") + opars.add_option("--keep-fields", default=False, action="store_true", + dest="keep_fields", + help="don't add fields from XML to SQL table") + opars.add_option("--ascii-db", default=False, action="store_true", + dest="ascii_db", + help="the SQL database stores ASCII instead of unicode") + opars.add_option("--replace", default=False, action="store_true", + dest="replace_table", + help="replace table i.e. delete and re-insert data") + opars.add_option("--backup", default=False, action="store_true", + dest="backup_table", + help="create backup of old table (breaks indices)") + opars.add_option("-d", "--debug", default=False, action="store_true", + dest="debug", + help="debug mode (more output)") + + (options, args) = opars.parse_args() + + if len(sys.argv) < 2 or options.filename is None or options.dsn is None: + print "importFMPXML "+version_string + opars.print_help() + sys.exit(1) + + if options.debug: + loglevel = logging.DEBUG + else: + loglevel = logging.INFO + + logging.basicConfig(level=loglevel, + format='%(asctime)s %(levelname)s %(message)s', + datefmt='%H:%M:%S') + + importFMPXML(options) + +def importFMPXML(options): + """SAX handler to import FileMaker XML file (FMPXMLRESULT format) into the table. + @param options: dict of options + @param options.dsn: database connection string + @param options.table: name of the table the xml shall be imported into + @param options.filename: xmlfile filename + @param options.update_fields: (optional) list of fields to update; default is to create all fields + @param options.id_field: (optional) field which uniquely identifies an entry for updating purposes. + @param options.sync_mode: (optional) really synchronise, i.e. delete entries not in XML file + @param options.lc_names: (optional) lower case and clean up field names from XML + @param options.keep_fields: (optional) don't add fields to SQL database + @param options.ascii_db: (optional) assume ascii encoding in db + @param options.replace_table: (optional) delete and re-insert data + """ + update_fields = None + + if getattr(options,'update_fields',None): + uf = {} + for f in options.update_fields.split(','): + (n,t) = f.split(':') + uf[n] = TableColumn(n,t) + + options.update_fields = uf + + if getattr(options,'id_field',None) and getattr(options,'replace_table',None): + logging.error("ABORT: sorry, you can't do both sync (id_field) and replace") + sys.exit(1) + + parser = sax.make_parser() + #The "consumer" is our own handler + consumer = xml_handler(options) + #Initialize Tenorsax with handler + handler = saxtools.tenorsax(consumer) + #Resulting tenorsax instance is the SAX handler + parser.setContentHandler(handler) + parser.setFeature(sax.handler.feature_namespaces, 1) + parser.parse(options.filename) + + -print "DONE!"