def _is_sql_wrapper(instance): """Determines if instance is a SQLAlchemy wrapper (ORM instance)""" try: class_mapper(instance.__class__) return True except: return False
def form_defaults(self): defaults = {} if "customer" in self.request.matchdict: customer_id = self.request.matchdict['customer'] session = DBSession() customer = session.query(Customer).filter_by(id=customer_id).first() if customer: field_names = [ p.key for p in class_mapper(Customer).iterate_properties ] form_fields = [ field[0] for field in customer_schema.attrs ] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(customer, field_name) # Default values for the contact subforms defaults['contact_list'] = [] for contact in customer.contacts: contact_defaults = {} field_names = [ p.key for p in class_mapper(CustomerContact).iterate_properties ] form_fields = [ field[0] for field in customer_contact_schmema.attrs ] for field_name in field_names: if field_name in form_fields: contact_defaults[field_name] = getattr(contact, field_name) contact_defaults['contact_id'] = contact.id defaults['contact_list'].append(contact_defaults) return defaults
def try_mapper(module): for attr in dir(module): if attr[0] == '_': continue try: cls = getattr(module, attr) class_mapper(cls) except Exception as ex: if isinstance(ex, sqlalchemy.exc.InvalidRequestError): if ex.message.startswith("One or more mappers failed to initialize"): return ex.message return None
def is_sqlalchemy_model(instance): """Return True if instance is an SQLAlchemy model instance.""" from sqlalchemy.orm.util import class_mapper from sqlalchemy.orm.exc import UnmappedClassError try: class_mapper(instance.__class__) except UnmappedClassError: return False else: return True
def __read__(self): id = None geom = None properties = {} for p in class_mapper(self.__class__).iterate_properties: if isinstance(p, ColumnProperty): if len(p.columns) != 1: # pragma: no cover raise NotImplementedError col = p.columns[0] val = getattr(self, p.key) if col.primary_key: id = val elif (isinstance(col.type, GeometryChsdi) and col.name == self.geometry_column_to_return().name): if hasattr(self, '_shape'): geom = self._shape elif val is not None: if len(val.data) > 1000000: raise HTTPBandwidthLimited( 'Feature ID %s: is too large' % self.id) geom = to_shape(val) elif (not col.foreign_keys and not isinstance(col.type, GeometryChsdi)): properties[p.key] = val properties = self.insert_label(properties) bbox = None try: bbox = geom.bounds except: pass return id, geom, properties, bbox
def _handleClass(self, classTag): fqCname=classTag.getAttribute('name') rc=self._classFromName(fqCname) if rc in self._classes: raise ValueError("Invalid report configuration '%s': Each class tag must have a unique value. '%s' found more than once" % (self._rptID, fqCname)) isOuter=classTag.getAttribute('outerjoin') if isOuter=='True': isOuter=True else: isOuter=False self._outerjoins[rc]=isOuter # Can explicitly set what to join on. Needed when one table has two foreign key columns to the same # parent (or child) table. onclause = classTag.getAttribute('onclause') if onclause: try: (fqCname, propName) = onclause.rsplit('.', 1) joincl = self._classFromName(fqCname) joinCol = getattr(joincl, propName) self._onclause[rc]=joinCol except: raise ValueError("Invalid report configuration '%s' : onclause '%s' attribute must point to a property in another ORM class" % (self._rptID, onclause)) # Get the set of unique attributes for this class, so that we # can keep track of which items in the UI should be unique uniqueAttributes=set() try: m=class_mapper(rc) for i in m.tables[0].indexes: if i.unique: if len(i.columns) == 1: attr=i.columns[0].name uniqueAttributes.add(attr) except UnmappedClassError: pass # Build configuration for each column columnTags=classTag.getElementsByTagName('column') for columnTag in columnTags: column=self._handleCol(columnTag) column.modelClass=rc # Column id must be unique idValue=column.id if idValue in self._columns: raise ValueError("Invalid report configuration '%s': Each column tag must have a 'id' value. '%s' found more than once" % (self._rptID, idValue)) # Check if this column is associated with a db column if column.dbColId: if column.dbColId in uniqueAttributes: column.unique=True dbCol=getattr(rc, column.dbColId, None) column.dbCol=dbCol self._dbcols[dbCol]=column self._columns[idValue]=column self._classes.append(rc)
def __read__(self): id = None geom = None properties = {} for p in class_mapper(self.__class__).iterate_properties: if isinstance(p, ColumnProperty): if len(p.columns) != 1: # pragma: no cover raise NotImplementedError col = p.columns[0] val = getattr(self, p.key) if col.primary_key: id = val elif isinstance(col.type, Geometry) and col.name == self.geometry_column_to_return().name: if hasattr(self, '_shape'): geom = self._shape else: geom = wkb.loads(str(val.geom_wkb)) elif not col.foreign_keys and not isinstance(col.type, Geometry): properties[p.key] = val if self.__add_properties__: for k in self.__add_properties__: properties[k] = getattr(self, k) return geojson.Feature(id=id, geometry=geom, properties=properties)
def __init__(self, session, mapped_class, children=None, attr_list=None): self.session = session self.mapped_class = mapped_class self.attr_list = attr_list self.columns = [] self.relationships = {} self.id = None for p in class_mapper(mapped_class).iterate_properties: if isinstance(p, ColumnProperty): if len(p.columns) != 1: raise NotImplementedError col = p.columns[0] if col.primary_key: self.id = p.key elif not col.foreign_keys and \ attr_list is None or p.key in attr_list: self.columns.append(p.key) elif children is not None and \ isinstance(p, RelationshipProperty) and \ p.key in children.keys(): rel = children[p.key] if "rest" not in rel or not isinstance(rel["rest"], REST): raise HTTPBadRequest( "Missing REST object for relationship %s" % p.key ) self.relationships[p.key] = rel
def __update__(self, feature): """ Called by the protocol on object update. Arguments: * ``feature`` The GeoJSON feature as received from the client. """ for p in class_mapper(self.__class__).iterate_properties: if not isinstance(p, ColumnProperty): continue col = p.columns[0] if isinstance(col.type, Geometry): geom = feature.geometry if geom and not isinstance(geom, geojson.geometry.Default): srid = col.type.srid shape = asShape(geom) setattr(self, p.key, from_shape(shape, srid=srid)) self._shape = shape elif not col.primary_key: if p.key in feature.properties: setattr(self, p.key, feature.properties[p.key]) if self.__add_properties__: for k in self.__add_properties__: setattr(self, k, feature.properties.get(k))
def __read__(self): id = None geom = None bbox = None properties = {} for p in class_mapper(self.__class__).iterate_properties: if isinstance(p, ColumnProperty): if len(p.columns) != 1: # pragma: no cover raise NotImplementedError col = p.columns[0] val = getattr(self, p.key) if col.primary_key: id = val elif (isinstance(col.type, GeometryChsdi) and col.name == self.geometry_column_to_return().name): if hasattr(self, '_shape') and \ len(self._shape) < MAX_FEATURE_GEOMETRY_SIZE: geom = self._shape elif val is not None and \ len(val.data) < MAX_FEATURE_GEOMETRY_SIZE: geom = to_shape(val) try: bbox = geom.bounds except: pass elif (not col.foreign_keys and not isinstance(col.type, GeometryChsdi)): properties[p.key] = val properties = self.insert_label(properties) return id, geom, properties, bbox
def _import_layer_wms(self, layer, messages): server = layer.ogc_server url = server.url_wfs or server.url if url is None: return for wms_layer in layer.layer.split(","): self._import_layer_attributes( url, wms_layer, layer.item_type, layer.name, layer.id, messages ) if layer.geo_table is not None: exclude = [] if layer.exclude_properties is None else layer.exclude_properties.split(",") last_update_date = layer.get_metadatas("lastUpdateDateColumn") if len(last_update_date) == 1: exclude.append(last_update_date[0].value) last_update_user = layer.get_metadatas("lastUpdateUserColumn") if len(last_update_user) == 1: exclude.append(last_update_user[0].value) try: cls = get_class(layer.geo_table, exclude_properties=exclude) for column_property in class_mapper(cls).iterate_properties: if isinstance(column_property, ColumnProperty) and \ len(column_property.columns) == 1 and \ not column_property.columns[0].primary_key and \ not column_property.columns[0].foreign_keys and \ not isinstance(column_property.columns[0].type, Geometry): messages.append(Message( None, column_property.key, None, [], "", "", (".".join(["edit", layer.item_type, str(layer.id)]), layer.name) )) except NoSuchTableError: exit(colorize("No such table '{}' for layer '{}'.".format(layer.geo_table, layer.name), RED))
def __read__(self): id = None geom = None properties = {} for p in class_mapper(self.__class__).iterate_properties: if isinstance(p, ColumnProperty): if len(p.columns) != 1: # pragma: no cover raise NotImplementedError col = p.columns[0] val = getattr(self, p.key) if col.primary_key: id = val elif isinstance(col.type, Geometry) and col.name == self.geometry_column_to_return().name: if hasattr(self, '_shape'): geom = self._shape elif val is not None: if len(val.data) > 1000000: raise HTTPBandwidtLimited('Feature ID %s: is too large' % self.id) geom = to_shape(val) elif not col.foreign_keys and not isinstance(col.type, Geometry): properties[p.key] = val if self.__add_properties__: for k in self.__add_properties__: properties[k] = getattr(self, k) properties = self.insertLabel(properties) return geojson.Feature(id=id, geometry=geom, properties=properties)
def meta_competence_edit_view(context, request): if IMetaCompetence.providedBy(context): add_form = False meta_competence = context context = meta_competence.__parent__ else: meta_competence = MetaCompetence() add_form = True errors = {} defaults = {} if 'form.submitted' in request.POST: try: # FormEncode validation defaults = dict(request.POST) form_result = meta_competence_schema.to_python(request.POST) except formencode.validators.Invalid, why: errors=why.error_dict else: # Apply schema fields to the project object field_names = [ p.key for p in class_mapper(MetaCompetence).iterate_properties ] changed = False for field_name in field_names: if field_name in form_result.keys(): if form_result[field_name] != getattr(meta_competence, field_name): setattr(meta_competence, field_name, form_result[field_name]) changed = True # Add onjective if this is the add form if add_form: session = DBSession() session.add(meta_competence) return HTTPFound(location = model_url(context, request))
def get_foreign_key_columns(clazz): '''Given a schema class, return {class column: foreign key class column}''' fk_cols = {} for column in class_mapper(clazz).columns: if column.foreign_keys: fk_cols[column] = next(iter(column.foreign_keys)).column return fk_cols
def __read__(self): """ Called by :py:attr:`.__geo_interface__`. """ id = None geom = None properties = {} for p in class_mapper(self.__class__).iterate_properties: if isinstance(p, ColumnProperty): if len(p.columns) != 1: # pragma: no cover raise NotImplementedError col = p.columns[0] val = getattr(self, p.key) if col.primary_key: id = val elif isinstance(col.type, Geometry): if hasattr(self, "_shape"): geom = self._shape elif val is not None: geom = to_shape(val) elif not col.foreign_keys: properties[p.key] = val if self.__add_properties__: for k in self.__add_properties__: properties[k] = getattr(self, k) return geojson.Feature(id=id, geometry=geom, properties=properties)
def __geo_interface__(self): """ Objects implement the Python Geo Interface, making them candidates to serialization with the ``geojson`` module, or Papyrus' GeoJSON renderer. """ id = None geom = None properties = {} if hasattr(self, '_shape'): geom = self._shape for p in class_mapper(self.__class__).iterate_properties: if not isinstance(p, ColumnProperty): continue col = p.columns[0] val = getattr(self, p.key) if col.primary_key: id = val elif isinstance(col.type, Geometry): if not geom: geom = wkb.loads(str(val.geom_wkb)) else: properties[p.key] = val return geojson.Feature(id=id, geometry=geom, properties=properties)
def _apply_data(self, invoice, converted): changed = False # Apply schema fields to the customer object field_names = [ p.key for p in class_mapper(Invoice).iterate_properties ] for field_name in field_names: if field_name in converted.keys(): if getattr(invoice, field_name) != converted[field_name]: setattr(invoice, field_name, converted[field_name]) changed = True if invoice.due_date != invoice.date + datetime.timedelta(days=converted['payment_term']): invoice.due_date = invoice.date + datetime.timedelta(days=converted['payment_term']) changed = True if converted['recurring_term'] and invoice.recurring_date != invoice.date + datetime.timedelta(days=converted['recurring_term']): invoice.recurring_date = invoice.date + datetime.timedelta(days=converted['recurring_term']) changed = True # Apply data of the items subforms session = DBSession() item_map = {} for item in invoice.items: item_map[item.id] = item for index, item_data in enumerate(converted['item_list']): if item_data['item_id']: item_id = item_data['item_id'] item = item_map[item_id] del item_map[item_id] else: item = InvoiceItem() item.invoice = invoice session.add(item) changed = True # Apply schema fields to the invoice item object field_names = [ p.key for p in class_mapper(InvoiceItem).iterate_properties ] for field_name in field_names: if field_name in item_data.keys(): if getattr(item, field_name) != item_data[field_name]: setattr(item, field_name, item_data[field_name]) changed = True if item.item_number != index: item.item_number = index changed = True # Remove invoice items that have been removed in the form for item in item_map.values(): invoice.items.remove(item) changed = True return changed
def get_columns(model): columns = [p.key for p in class_mapper(model).iterate_properties if isinstance(p, (ColumnProperty, SynonymProperty)) \ and not p.key.startswith('_')] for parent in model.mro(): columns += [key for key, value in parent.__dict__.iteritems() if isinstance(value, hybrid_property)] return columns
def add_class_properties_xsd(self, tb, cls): """ Add the XSD for the class properties to the ``TreeBuilder``. And call the user ``sequence_callback``. """ for p in class_mapper(cls).iterate_properties: if isinstance(p, ColumnProperty): self.add_column_property_xsd(tb, p) if self.sequence_callback: self.sequence_callback(tb, cls)
def form_defaults(self): defaults = {} session = DBSession() company = session.query(Company).first() field_names = [ p.key for p in class_mapper(Company).iterate_properties ] form_fields = [ field[0] for field in company_schema.attrs ] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(company, field_name) return defaults
def form_defaults(self): session = DBSession() company = session.query(Company).first() defaults = { 'currency' : u'CHF', 'payment_term' : 30, 'tax' : company.tax, } if "invoice" in self.request.matchdict: invoice_id = self.request.matchdict['invoice'] invoice = session.query(Invoice).filter_by(id=invoice_id).first() if invoice: field_names = [ p.key for p in class_mapper(Invoice).iterate_properties ] form_fields = [ field[0] for field in invoice_schema.attrs ] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(invoice, field_name) defaults['payment_term'] = (invoice.due_date - invoice.date).days if invoice.recurring_date: defaults['recurring_term'] = (invoice.recurring_date - invoice.date).days else: defaults['recurring_term'] = None # Default values for the item subforms defaults['item_list'] = [] # Make test happy invoice.items.sort(key=lambda obj: obj.item_number) for item in invoice.items: item_defaults = {} field_names = [ p.key for p in class_mapper(InvoiceItem).iterate_properties ] form_fields = [ field[0] for field in invoice_item_schema.attrs ] for field_name in field_names: if field_name in form_fields: item_defaults[field_name] = getattr(item, field_name) item_defaults['item_id'] = item.id defaults['item_list'].append(item_defaults) return defaults
def disconnect_from_db(docs): '''Make sure that docs won't synchronise with the database if changed.''' for d in docs: #make_transient removes the primary keys, hack to back them up and #reset them after id_attrs = [a.name for a in class_mapper(d.__class__).primary_key] id_vals = {a: getattr(d, a) for a in id_attrs} session.make_transient(d) for attr, val in id_vals.iteritems(): setattr(d, attr, val)
def _get_col_epsg(mapped_class, geom_attr): """Get the EPSG code associated with a geometry attribute. Arguments: geom_attr the key of the geometry property as defined in the SQLAlchemy mapper. If you use ``declarative_base`` this is the name of the geometry attribute as defined in the mapped class. """ col = class_mapper(mapped_class).get_property(geom_attr).columns[0] return col.type.srid
def __set__(self, obj, val): from c2cgeoportal.models import DBSession o = getattr(obj, self.target) # if the obj as no child object or if the child object # does not correspond to the new value then we need to # read a new child object from the database if not o or getattr(o, self.value_attr) != val: relationship_property = class_mapper(obj.__class__).get_property(self.target) child_cls = relationship_property.argument o = DBSession.query(child_cls).filter(getattr(child_cls, self.value_attr) == val).first() setattr(obj, self.target, o)
def __set__(self, obj, val): from c2cgeoportal.models import DBSession o = getattr(obj, self.target) # if the obj as no child object or if the child object # does not correspond to the new value then we need to # read a new child object from the database if not o or getattr(o, self.value_attr) != val: relationship_property = class_mapper(obj.__class__) \ .get_property(self.target) child_cls = relationship_property.argument o = DBSession.query(child_cls).filter( getattr(child_cls, self.value_attr) == val).first() setattr(obj, self.target, o)
def _apply_data(self, customer, converted): changed = False session = DBSession() # Apply schema fields to the customer object field_names = [ p.key for p in class_mapper(Customer).iterate_properties ] for field_name in field_names: if field_name in converted.keys(): if getattr(customer, field_name) != converted[field_name]: setattr(customer, field_name, converted[field_name]) changed = True # Apply data of the contact subforms contact_map = {} for contact in customer.contacts: contact_map[contact.id] = contact for contact_data in converted['contact_list']: if contact_data['contact_id']: contact_id = contact_data['contact_id'] contact = contact_map[contact_id] del contact_map[contact_id] else: contact = CustomerContact() contact.customer = customer session.add(contact) changed = True # Apply schema fields to the customer contact object field_names = [ p.key for p in class_mapper(CustomerContact).iterate_properties ] for field_name in field_names: if field_name in contact_data.keys(): if getattr(contact, field_name) != contact_data[field_name]: setattr(contact, field_name, contact_data[field_name]) changed = True # Remove contact items that have been removed in the form for contact in contact_map.values(): # FIXME: what happens to existing invoices that loose their contact? customer.contacts.remove(contact) changed = True return changed
def get_layer_class(layer, with_last_update_columns=False): """ Get the SQLAlchemy class to edit a GeoMapFish layer :param layer: :param with_last_update_columns: False to just have a class to access to the table and be able to modify the last_update_columns, True to have a correct class to build the UI (without the hidden column). :return: SQLAlchemy class """ # Exclude the columns used to record the last features update exclude = [] if layer.exclude_properties is None else layer.exclude_properties.split( ",") if with_last_update_columns: last_update_date = Layers.get_metadata(layer, "lastUpdateDateColumn") if last_update_date is not None: exclude.append(last_update_date) last_update_user = Layers.get_metadata(layer, "lastUpdateUserColumn") if last_update_user is not None: exclude.append(last_update_user) else: exclude = [] m = Layers.get_metadata(layer, "editingAttributesOrder") attributes_order = m.split(',') if m else None m = Layers.get_metadata(layer, "readonlyAttributes") readonly_attributes = m.split(',') if m else None primary_key = Layers.get_metadata(layer, "geotablePrimaryKey") cls = get_class(str(layer.geo_table.format(os.environ)), exclude_properties=exclude, primary_key=primary_key, attributes_order=attributes_order, readonly_attributes=readonly_attributes) mapper = class_mapper(cls) column_properties = [ p.key for p in mapper.iterate_properties if isinstance(p, ColumnProperty) ] for attribute_name in attributes_order or []: if attribute_name not in column_properties: table = mapper.mapped_table log.warning( 'Attribute "{}" does not exists in table "{}".\n' 'Please correct metadata "editingAttributesOrder" in layer "{}" (id={}).\n' 'Available attributes are: {}.'.format( attribute_name, '{}.{}'.format(table.schema, table.name), layer.name, layer.id, ', '.join(column_properties))) return cls
def _import_layer_wms(self, layer: "main.Layer", messages: List[str]) -> None: server = layer.ogc_server url = server.url_wfs or server.url if url is None: return if layer.ogc_server.wfs_support: for wms_layer in layer.layer.split(","): self._import_layer_attributes(url, wms_layer, layer.item_type, layer.name, messages) if layer.geo_table is not None and layer.geo_table != "": try: cls = get_layer_class(layer, with_last_update_columns=True) for column_property in class_mapper(cls).iterate_properties: if isinstance(column_property, ColumnProperty) and len( column_property.columns) == 1: column = column_property.columns[0] if not column.primary_key and not isinstance( column.type, Geometry): if column.foreign_keys: if column.name == "type_id": name = "type_" elif column.name.endswith("_id"): name = column.name[:-3] else: name = column.name + "_" else: name = column_property.key messages.append( Message( None, name, None, [], "", "", (".".join([ "edit", layer.item_type, str(layer.id) ]), layer.name), )) except NoSuchTableError: print( colorize( "ERROR! No such table '{}' for layer '{}'.".format( layer.geo_table, layer.name), Color.RED, )) print(colorize(traceback.format_exc(), Color.RED)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise
def __set__(self, obj: str, val: str) -> None: from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel o = getattr(obj, self.target) # if the obj as no child object or if the child object # does not correspond to the new value then we need to # read a new child object from the database if not o or getattr(o, self.value_attr) != val: relationship_property = class_mapper(obj.__class__).get_property( self.target) child_cls = relationship_property.argument o = DBSession.query(child_cls).filter( getattr(child_cls, self.value_attr) == val).first() setattr(obj, self.target, o)
def __init__(self, feature): """ Called by the protocol on object creation. Arguments: * ``feature`` The GeoJSON feature as received from the client. """ for p in class_mapper(self.__class__).iterate_properties: if not isinstance(p, ColumnProperty): continue if p.columns[0].primary_key: primary_key = p.key setattr(self, primary_key, feature.id) self.__update__(feature)
def find_file_manager(self, target): if isinstance(target, FileAttribute): assert hasattr(target, 'class_') target = target.class_ else: if not inspect.isclass(target): target = type(target) assert hasattr(target, 'metadata') assert class_mapper(target) is not None if target in registry: return registry[target] if target.metadata in registry: return registry[target.metadata] return file_manager
def _get_geom_col_info(layer): """ Return information about the layer's geometry column, namely a ``(name, srid)`` tuple, where ``name`` is the name of the geometry column, and ``srid`` its srid. This function assumes that the names of geometry attributes in the mapped class are the same as those of geometry columns. """ mapped_class = get_class(str(layer.geoTable)) for p in class_mapper(mapped_class).iterate_properties: if not isinstance(p, ColumnProperty): continue # pragma: no cover col = p.columns[0] if isinstance(col.type, Geometry): return col.name, col.type.srid raise HTTPInternalServerError() # pragma: no cover
def __init__(self, feature=None): """ Called by the protocol on object creation. Arguments: * ``feature`` The GeoJSON feature as received from the client. """ if feature: for p in class_mapper(self.__class__).iterate_properties: if not isinstance(p, ColumnProperty): continue if p.columns[0].primary_key: primary_key = p.key setattr(self, primary_key, feature.id) self.__update__(feature)
def test_add_column_property_xsd(self, column_mock, proxy_mock): from c2cgeoportal_geoportal.lib.xsd import XSDGenerator from sqlalchemy.orm.util import class_mapper gen = XSDGenerator(include_foreign_keys=True) tb = Mock() mapper = class_mapper(self.cls) p = mapper.attrs["child1_id"] gen.add_column_property_xsd(tb, p) proxy_mock.assert_called_once_with(tb, p) p = mapper.attrs["other"] gen.add_column_property_xsd(tb, p) column_mock.assert_called_once_with(tb, p)
def __init__(self, session, mapped_class): self.session = session self.mapped_class = mapped_class self.columns = [] self.id = None for p in class_mapper(mapped_class).iterate_properties: if isinstance(p, ColumnProperty): if len(p.columns) != 1: raise NotImplementedError col = p.columns[0] if col.primary_key: self.id = p.key elif not col.foreign_keys: self.columns.append(p.key)
def test_add_association_proxy_xsd(self): from xml.etree.ElementTree import TreeBuilder, tostring from sqlalchemy.orm.util import class_mapper from c2cgeoportal_geoportal.lib.xsd import XSDGenerator gen = XSDGenerator(include_foreign_keys=True) mapper = class_mapper(self.cls) tb = TreeBuilder() gen.add_association_proxy_xsd(tb, mapper.attrs["child1_id"]) e = tb.close() self.assertEqual( '<xsd:element minOccurs="0" nillable="true" name="child1">' "<xsd:simpleType>" '<xsd:restriction base="xsd:string">' '<xsd:enumeration value="foo" />' '<xsd:enumeration value="zad" />' '<xsd:enumeration value="bar" />' "</xsd:restriction>" "</xsd:simpleType>" "</xsd:element>", tostring(e).decode("utf-8"), ) # Test child2 enumeration is ordered by Child.custom_order tb = TreeBuilder() gen.add_association_proxy_xsd(tb, mapper.attrs["child2_id"]) e = tb.close() self.assertEqual( '<xsd:element name="child2">' "<xsd:simpleType>" '<xsd:restriction base="xsd:string">' '<xsd:enumeration value="zad" />' '<xsd:enumeration value="foo" />' '<xsd:enumeration value="bar" />' "</xsd:restriction>" "</xsd:simpleType>" "</xsd:element>", tostring(e).decode("utf-8"), )
def _get_geom_col_info(layer: "main.Layer") -> Tuple[str, int]: """Return information about the layer's geometry column, namely a ``(name, srid)`` tuple, where ``name`` is the name of the geometry column, and ``srid`` its srid. This function assumes that the names of geometry attributes in the mapped class are the same as those of geometry columns. """ mapped_class = get_layer_class(layer) for p in class_mapper(mapped_class).iterate_properties: if not isinstance(p, ColumnProperty): continue col = p.columns[0] if isinstance(col.type, Geometry): return col.name, col.type.srid raise HTTPInternalServerError( 'Failed getting geometry column info for table "{0!s}".'.format( layer.geo_table))
def _apply_data(self, company, converted): # Apply schema fields to the company object changed = False field_names = [ p.key for p in class_mapper(Company).iterate_properties ] for field_name in field_names: if field_name in converted.keys(): if getattr(company, field_name) != converted[field_name]: setattr(company, field_name, converted[field_name]) changed = True if 'logo' in converted and converted['logo']: logo_path = os.path.join(os.path.dirname(__file__), 'templates', 'static', 'uploads', 'logo.jpg') fd = open(logo_path, 'wb') fd.write(converted['logo'].file.read()) fd.close() changed = True return changed
def _import_layer_wms(self, layer, messages): server = layer.ogc_server url = server.url_wfs or server.url if url is None: return for wms_layer in layer.layer.split(","): self._import_layer_attributes(url, wms_layer, layer.item_type, layer.name, messages) if layer.geo_table is not None and layer.geo_table != "": exclude = [] if layer.exclude_properties is None else layer.exclude_properties.split( ",") last_update_date = layer.get_metadatas("lastUpdateDateColumn") if len(last_update_date) == 1: exclude.append(last_update_date[0].value) last_update_user = layer.get_metadatas("lastUpdateUserColumn") if len(last_update_user) == 1: exclude.append(last_update_user[0].value) try: cls = get_class(layer.geo_table, exclude_properties=exclude) for column_property in class_mapper(cls).iterate_properties: if isinstance(column_property, ColumnProperty) and len( column_property.columns) == 1: column = column_property.columns[0] if not column.primary_key and not isinstance( column.type, Geometry): if column.foreign_keys: name = "type_" if column.name == "type_id" else \ column.name[0:column.name.rindex("_id")] else: name = column_property.key messages.append( Message(None, name, None, [], "", "", (".".join([ "edit", layer.item_type, str(layer.id) ]), layer.name))) except NoSuchTableError: print( colorize( "ERROR! No such table '{}' for layer '{}'.".format( layer.geo_table, layer.name), RED)) print(colorize(traceback.format_exc(), RED)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise
def _xsd_sequence_callback(tb, cls): from c2cgeoportal.models import DBSession for k, p in cls.__dict__.iteritems(): if not isinstance(p, _association_proxy): continue relationship_property = class_mapper(cls) \ .get_property(p.target) target_cls = relationship_property.argument query = DBSession.query(getattr(target_cls, p.value_attr)) attrs = {} attrs['minOccurs'] = str(0) attrs['nillable'] = 'true' attrs['name'] = k with tag(tb, 'xsd:element', attrs) as tb: with tag(tb, 'xsd:simpleType') as tb: with tag(tb, 'xsd:restriction', {'base': 'xsd:string'}) as tb: for value, in query: with tag(tb, 'xsd:enumeration', {'value': value}): pass
def _xsd_sequence_callback(tb, cls): from c2cgeoportal.models import DBSession for k, p in cls.__dict__.iteritems(): if not isinstance(p, _AssociationProxy): continue relationship_property = class_mapper(cls) \ .get_property(p.target) target_cls = relationship_property.argument query = DBSession.query(getattr(target_cls, p.value_attr)) attrs = {} attrs["minOccurs"] = str(0) attrs["nillable"] = "true" attrs["name"] = k with tag(tb, "xsd:element", attrs) as tb: with tag(tb, "xsd:simpleType") as tb: with tag(tb, "xsd:restriction", {"base": "xsd:string"}) as tb: for value, in query: with tag(tb, "xsd:enumeration", {"value": value}): pass
def _apply_data(self, company, converted): # Apply schema fields to the company object changed = False field_names = [p.key for p in class_mapper(Company).iterate_properties] for field_name in field_names: if field_name in converted.keys(): if getattr(company, field_name) != converted[field_name]: setattr(company, field_name, converted[field_name]) changed = True if 'logo' in converted and converted['logo']: logo_path = os.path.join(os.path.dirname(__file__), 'templates', 'static', 'uploads', 'logo.jpg') fd = open(logo_path, 'wb') fd.write(converted['logo'].file.read()) fd.close() changed = True return changed
def indicator_edit_view(context, request): if IIndicator.providedBy(context): indicator = context indicator_set = indicator.indicator_set add_form = False else: indicator = Indicator() indicator_set = context.__parent__ add_form = True competences_container = find_interface(context, ICompetences) errors = {} defaults = {} if 'form.submitted' in request.POST: try: # FormEncode validation defaults = dict(request.POST) form_result = indicator_schema.to_python(request.POST) except formencode.validators.Invalid, why: errors = why.error_dict else: # Apply schema fields to the project object field_names = [ p.key for p in class_mapper(Indicator).iterate_properties ] changed = False for field_name in field_names: if field_name in form_result.keys(): if form_result[field_name] != getattr( indicator, field_name): setattr(indicator, field_name, form_result[field_name]) changed = True # Add project if this is the add form if add_form: session = DBSession() indicator.indicator_set = indicator_set indicator.index = indicator_set.indicators.count() - 1 session.add(indicator) return HTTPFound( location=model_url(competences_container, request))
def check_set_sample_type(target, value, oldvalue, initiator): # pylint: disable=W0613 if isinstance(target, Sample) \ and value == SAMPLE_TYPES.STOCK \ and oldvalue != SAMPLE_TYPES.STOCK: sess = object_session(target) if target.id is None: # We need a sample ID for the following execute statement to work. sess.flush() mdp = target.molecule_design_pool if mdp.id is None: sess.add(type(mdp), mdp) sess.flush() ss_tbl = class_mapper(StockSample).local_table sess.execute( insert(ss_tbl, values=dict( sample_id=target.sample_id, molecule_design_set_id=target.molecule_design_pool.id, supplier_id=target.supplier.id, molecule_type_id=target.molecule_type.id, concentration=target.concentration)))
def competence_edit_view(context, request): session = DBSession() meta_competences = session.query(MetaCompetence).all() if ICompetence.providedBy(context): competence = context context = competence.__parent__ add_form = False else: competence = Competence() add_form = True errors = {} defaults = {} if 'form.submitted' in request.POST: try: # FormEncode validation defaults = dict(request.POST) form_result = competence_schema.to_python(request.POST) except formencode.validators.Invalid, why: errors = why.error_dict else: # Apply schema fields to the project object field_names = [ p.key for p in class_mapper(Competence).iterate_properties ] changed = False for field_name in field_names: if field_name in form_result.keys(): if form_result[field_name] != getattr( competence, field_name): setattr(competence, field_name, form_result[field_name]) changed = True # Add project if this is the add form if add_form: session.add(competence) return HTTPFound(location=model_url(context, request))
def test_add_column_readonly(self): from c2cgeoportal_geoportal.lib.xsd import XSDGenerator from sqlalchemy.orm.util import class_mapper from xml.etree.ElementTree import TreeBuilder, tostring gen = XSDGenerator(include_foreign_keys=True) mapper = class_mapper(self.cls) tb = TreeBuilder() p = mapper.attrs['readonly'] gen.add_column_property_xsd(tb, p) e = tb.close() self.assertEqual( '<xsd:element minOccurs="0" name="readonly" nillable="true" type="xsd:string">' '<xsd:annotation>' '<xsd:appinfo>' '<readonly value="true" />' '</xsd:appinfo>' '</xsd:annotation>' '</xsd:element>', tostring(e).decode("utf-8"))
def add_association_proxy_xsd(self, tb, column_property): from c2cgeoportal_commons.models import DBSession column = column_property.columns[0] proxy = column.info['association_proxy'] attribute = column_property.class_attribute cls = attribute.parent.entity association_proxy = getattr(cls, proxy) relationship_property = class_mapper(cls) \ .get_property(association_proxy.target) target_cls = relationship_property.argument query = DBSession.query( getattr(target_cls, association_proxy.value_attr)) attrs = {} if association_proxy.nullable: attrs["minOccurs"] = "0" attrs["nillable"] = "true" attrs["name"] = proxy with tag(tb, "xsd:element", attrs) as tb: with tag(tb, "xsd:simpleType") as tb: with tag(tb, "xsd:restriction", {"base": "xsd:string"}) as tb: for value, in query: with tag(tb, "xsd:enumeration", {"value": value}): pass self.element_callback(tb, column)
def _import_layer_wms(self, layer, messages): server = layer.ogc_server url = server.url_wfs or server.url if url is None: return for wms_layer in layer.layer.split(","): self._import_layer_attributes(url, wms_layer, layer.item_type, layer.name, layer.id, messages) if layer.geo_table is not None and layer.geo_table != "": exclude = [] if layer.exclude_properties is None else layer.exclude_properties.split( ",") last_update_date = layer.get_metadatas("lastUpdateDateColumn") if len(last_update_date) == 1: exclude.append(last_update_date[0].value) last_update_user = layer.get_metadatas("lastUpdateUserColumn") if len(last_update_user) == 1: exclude.append(last_update_user[0].value) try: cls = get_class(layer.geo_table, exclude_properties=exclude) for column_property in class_mapper(cls).iterate_properties: if isinstance(column_property, ColumnProperty) and \ len(column_property.columns) == 1 and \ not column_property.columns[0].primary_key and \ not column_property.columns[0].foreign_keys and \ not isinstance(column_property.columns[0].type, Geometry): messages.append( Message( None, column_property.key, None, [], "", "", (".".join( ["edit", layer.item_type, str(layer.id)]), layer.name))) except NoSuchTableError: exit( colorize( "No such table '{}' for layer '{}'.".format( layer.geo_table, layer.name), RED))
def add_class_properties_xsd(self, tb: str, cls: DeclarativeMeta) -> None: """Add the XSD for the class properties to the ``TreeBuilder``. And call the user ``sequence_callback``.""" mapper = class_mapper(cls) properties = [] if cls.__attributes_order__: for attribute_name in cls.__attributes_order__: attr = mapper.attrs.get(attribute_name) if attr: properties.append(attr) # Add other attributes for p in mapper.iterate_properties: if p not in properties: properties.append(p) else: properties = mapper.iterate_properties for p in properties: if isinstance(p, ColumnProperty): self.add_column_property_xsd(tb, p) if self.sequence_callback: self.sequence_callback(tb, cls)
def get_layer_class( layer: "main.Layer", with_last_update_columns: bool = False ) -> sqlalchemy.ext.declarative.api.ConcreteBase: """ Get the SQLAlchemy class to edit a GeoMapFish layer :param layer: :param with_last_update_columns: False to just have a class to access to the table and be able to modify the last_update_columns, True to have a correct class to build the UI (without the hidden column). :return: SQLAlchemy class """ # Exclude the columns used to record the last features update exclude = [] if layer.exclude_properties is None else layer.exclude_properties.split( ",") if with_last_update_columns: last_update_date = Layers.get_metadata(layer, "lastUpdateDateColumn") if last_update_date is not None: exclude.append(last_update_date) last_update_user = Layers.get_metadata(layer, "lastUpdateUserColumn") if last_update_user is not None: exclude.append(last_update_user) else: exclude = [] m = Layers.get_metadata(layer, "editingAttributesOrder") attributes_order = m.split(",") if m else None m = Layers.get_metadata(layer, "readonlyAttributes") readonly_attributes = m.split(",") if m else None m = Layers.get_metadata(layer, "editingEnumerations") enumerations_config = json.loads(m) if m else None primary_key = Layers.get_metadata(layer, "geotablePrimaryKey") cls = get_class( str(layer.geo_table.format(**os.environ)), exclude_properties=exclude, primary_key=primary_key, attributes_order=attributes_order, enumerations_config=enumerations_config, readonly_attributes=readonly_attributes, ) mapper = class_mapper(cls) column_properties = [ p.key for p in mapper.iterate_properties if isinstance(p, ColumnProperty) ] for attribute_name in attributes_order or []: if attribute_name not in column_properties: table = mapper.mapped_table LOG.warning( 'Attribute "%s" does not exists in table "%s.%s".\n' 'Please correct metadata "editingAttributesOrder" in layer "%s" (id=%s).\n' "Available attributes are: %s.", attribute_name, table.schema, table.name, layer.name, layer.id, ", ".join(column_properties), ) return cls
def own_mapper(cls): try: return class_mapper(cls) except UnmappedClassError: return mapper
def is_mapped_class(cls): try: class_mapper(cls) return True except: return False
def _is_sa_class_mapped(cls): try: class_mapper(cls) return True except: return False
# Add student if this is the add form if add_form: session = DBSession() session.add(teacher) if not form_result['password']: reset_url = model_url(get_root(request), request, 'retrieve_password.html') teacher.send_password_reset(reset_url) return HTTPFound(location = model_url(context, request)) elif 'form.cancel' in request.POST: return HTTPFound(location = model_url(context, request)) else: if not add_form: field_names = [ p.key for p in class_mapper(Teacher).iterate_properties ] for field_name in field_names: defaults[field_name] = getattr(teacher, field_name) defaults['portrait'] = '' form = render_template('templates/teacher_edit.pt', teacher=teacher, add_form=add_form, api=TemplateAPI(request)) # FormEncode fills template with default values form = htmlfill.render(form, defaults=defaults, errors=errors) return Response(form)
def teacher_edit_view(context, request): if ITeacher.providedBy(context): teacher = context context = teacher.__parent__ add_form = False else: teacher = Teacher(id=uuid.uuid4()) add_form = True errors = {} defaults = {} if 'form.submitted' in request.POST: try: # FormEncode validation defaults = dict(request.POST) state = FormencodeState() state.user_id = teacher.user_name if add_form: form_result = teacher_add_schema.to_python(request.POST, state) else: form_result = teacher_schema.to_python(request.POST, state) except formencode.validators.Invalid, why: errors=why.error_dict else: changed = False # Convert password to SHA hash if form_result.get('password', None): form_result['password'] = '******' % sha.new(form_result['password']).hexdigest() changed = True # Handle portrait upload if form_result['portrait'] is not None: # Scale image and convert to JPEG im = Image.open(form_result['portrait'].file) im.thumbnail((128, 128),Image.ANTIALIAS) # Convert to RGB if neccessary if im.mode != "RGB": im = im.convert("RGB") outfile = StringIO() im.save(outfile, "JPEG") outfile.seek(0) teacher.portrait = File('portrait.jpg', outfile.read()) changed = True del form_result['portrait'] # Apply schema fields to the student object field_names = [ p.key for p in class_mapper(Teacher).iterate_properties ] for field_name in field_names: if field_name in form_result.keys(): if form_result[field_name] != getattr(teacher, field_name): setattr(teacher, field_name, form_result[field_name]) changed = True # Add student if this is the add form if add_form: session = DBSession() session.add(teacher) if not form_result['password']: reset_url = model_url(get_root(request), request, 'retrieve_password.html') teacher.send_password_reset(reset_url) return HTTPFound(location = model_url(context, request))
def column_names(self): return [ col.name for col in class_mapper(self.__class__).mapped_table.c ]
def _get_primary_key(self): '''This method introspects the underlining model and detects the primary key of the model.''' return class_mapper(self.model_cls).primary_key