Source code for datconv.outconn.crate.ddl

# -*- coding: utf-8 -*-
"""This module implements Datconv Output Connector which generates CREATE TABLE cause in database crate.io dialect. 
Output of this connector should be treated as starting point for further manual edition, it is not recommended to use it for automatic table generation.
This connector should be used with Writer: :ref:`writers_dcxpaths` with options ``add_header: false`` and ``add_type: true``.
"""

# Standard Python Libs

# Datconv packages
from .. import LIST
from . import Keywords


Log = None
"""Log varaible is automatically set by main datconv script using logging.getLogger method.
Use it for logging messages in need.
"""

_CrateType = { \
    'int': 'integer', \
    'float': 'float', \
    'str': 'string', \
    }

[docs]class DCConnector: """Please see constructor description for more details.""" def __init__(self, table, path, mode = 'w', schema = 'doc', \ check_keywords = True, lowercase = 1, no_underscore = 1, \ column_constraints = {}, common_column_constraints = [], table_constraints = []): """Parameters are usually passed from YAML file as subkeys of OutConnector:CArg key. :param table: name of the table. :param path: relative or absolute path to output file. :param mode: output file opening mode. :param schema: schema of the table. :param check_keywords: if true, prevents conflicts with SQL keywords. Data field names that are in conflict will be suffixed with undderscore. :param lowercase: if >1, all JSON keys will be converted to lower-case; if =1, only first level keys; if =0, no conversion happen. :param no_underscore: if >1, leading ``_`` will be removed from all JSON keys; if =1, only from first level of keys; if =0, option is disabled. :param column_constraints: dictionary: key=column name, value=column constraint. :param common_column_constraints: column constatins to be added after column definitions. Should be declared as string. :param table_constraints: table constatins and creation options. Should be declared as string. For more detailed descriptions see :ref:`conf_template.yaml <outconn_crate_conf_template>` file in this module folder. """ assert Log is not None import datconv.outconn.crate datconv.outconn.crate.PckLog = Log self._path = path self._out = open(path, mode) self._tablename = table self._tableschema = schema self._chkkwd = check_keywords if check_keywords: if self._tablename.upper() in Keywords: Log.warning('Conflict with Crate key-word. Table %s remaned to %s' % (self._tablename, self._tablename + '_')) self._tablename += '_' self._lowercase = lowercase if self._lowercase > 0: self._tablename = self._tablename.lower() self._no_underscore = no_underscore self._cconst = column_constraints self._ccconst = common_column_constraints self._tconst = table_constraints self._fields = [] self._fields_names = set() def supportedInterfases(self): return LIST def tryObject(self, obj): return isinstance(obj, list) def pushObject(self, obj): # TODO: Add suport for OBJECTS (depper levels) (idea: recursive call with taking xpatha[3], xpatha[4], ...) #obj: [ColumnName,RecordType,XPath,Default,DataType] if len(obj) < 5: return xpatha = obj[2].split('/') if len(xpatha) < 3: return fname = xpatha[2] if fname[0] == '@': #XML property fname = fname[1:] if '[' in fname: fname = fname.split('[')[0] is_array = True else: is_array = False if len(xpatha) > 3: ftype = 'object' else: ftype = _CrateType[obj[4]] if not is_array and ftype != 'object': fname = obj[0] if self._lowercase > 0: fname = fname.lower() if self._no_underscore > 0: if fname[0] == '_': fname = fname[1:] if self._chkkwd: if fname.upper() in Keywords: Log.warning('Conflict with Crate key-word. %s remaned to %s' % (fname, fname + '_')) fname += '_' if fname in self._fields_names: return self._fields_names.add(fname) if is_array: ftype = 'array(%s)' % ftype if fname in self._cconst: self._fields.append(fname + ' ' + ftype + ' ' + self._cconst[fname]) else: self._fields.append(fname + ' ' + ftype) def onFinish(self, bSuccess): if bSuccess: sql = ''' CREATE TABLE "%s"."%s" ( %s ) %s; ''' % ( self._tableschema, self._tablename, \ ',\n '.join(self._fields + self._ccconst) , \ '\n'.join(self._tconst)) self._out.write(sql) if Log: Log.info('Output saved to %s' % self._path) self._out.close()