def _create_table(schema, catalog_name, collection_name, model, tablename=None): """ Returns a SQL statement to create a table in a schema The table fields are constructed from the specs :param schema: :param collection_name: :param specs: :param tablename: if None, collection_name is used :return: """ specs = get_field_specifications(model) order = _autorized_order(get_field_order(model), catalog_name, collection_name) catalog = GOBModel().get_catalog(catalog_name) catalog_description = quote_sql_string(catalog['description']) fields = [] for field_name in order: field_spec = specs[field_name] field_description = quote_sql_string(field_spec['description']) if field_spec['type'] in REFERENCE_TYPES: for reference_field in get_reference_fields(field_spec): name = joined_names(field_name, reference_field) fields.append( _create_field(name, fully_qualified_type_name(String), f"{field_description} ({reference_field})")) elif field_spec['type'] in JSON_TYPES: for field, spec in field_spec['attributes'].items(): name = joined_names(field_name, field) # Make all JSON attribute columns of type String (in case the resulting values are merged into a list) fields.append( _create_field(name, fully_qualified_type_name(String), f"{field_description} ({field})")) else: fields.append( _create_field(field_name, field_spec['type'], field_description)) field_lengths = [len(field['name']) for field in fields] max_length = max(field_lengths) if field_lengths else 1 table_name = (f"{_quote(schema)}.{_quote(tablename or collection_name)}") table_fields = ",\n ".join( [f"{field['name']:{max_length}} {field['type']}" for field in fields]) comments = ";\n".join([ f"COMMENT ON COLUMN {table_name}.{field['name']:{max_length}} " f"IS {SQL_QUOTATION_MARK}{field['description']}{SQL_QUOTATION_MARK}" for field in fields ]) primary_key = f",PRIMARY KEY ({UNIQUE_ID})" if UNIQUE_ID in order else "" return f"""
def __init__(self, entities, model=None, ignore_fields=None, header=True): if model: self.field_specs = get_field_specifications(model) self.field_order = [ f for f in get_field_order(model) if f not in (ignore_fields or []) ] else: self.field_specs, self.field_order = {}, [] self.field_names = self._get_field_names() self.include_header = header self.entities = entities
def _create_indexes(model): indexes = [] for field, spec in get_field_specifications(model).items(): if field == model['entity_id'] or re.compile(r"(^|.+_)ref$").match( field) or field == FIELD.LAST_EVENT: indexes.append( {'field': field} ) # Plain entity id, full entity id (ref) or rel. foreign key (eg dst_ref) elif "GOB.Geo" in spec['type']: indexes.append({'field': field, 'method': "gist"}) # Spatial index elif spec['type'] == "GOB.Reference" and "ref" in get_reference_fields( spec): indexes.append({'field': f"{field}_ref"}) # Foreign key index return indexes
def csv_entities(entities, model, ignore_fields=None): """ Yield the given entities as a list, starting with a header. :param entities: :param model: :return: """ ignore_fields = ignore_fields or [] field_specifications = get_field_specifications(model) field_order = [f for f in get_field_order(model) if f not in ignore_fields] header = _csv_header(field_specifications, field_order) for entity in entities: if header: yield _csv_line(header) header = None fields = _csv_record(entity, field_specifications, field_order) yield _csv_line(fields)
def test_get_field_specifications(self): model = { 'catalog': 'any catalog', 'entity_id': 'any entity id name', 'all_fields': { 'skip_on_type': {'type': 'GOB.VeryManyReference'}, '_hash': "skip on field name", 'any_attr': {'type': 'whatever type'} } } result = get_field_specifications(model) expect = { 'any_attr': {'type': 'whatever type'}, 'ref': { 'description': 'identificatie_volgnummer or identificatie', 'entity_id': 'any entity id name', 'type': 'GOB.String' } } self.assertEqual(result, expect)