Exemplo n.º 1
0
def orm_mapping(event=None):
    # Register table type for grokked ModelBase classes
    registered = []
    for setobject_type in setobject_type_registry.values():
        class_name = setobject_type.__name__
        table_name = setobject_type.get_table_name()
        # Create SA table type
        if setobject_table_registry.get_by_table(table_name) == None:
            table_type = Table(table_name, metadata, autoload=True)
        else:
            table_type = setobject_table_registry.lookup_by_table(table_name)
        # And register it.
        setobject_table_registry.register_type(class_name, table_name, table_type)
        registered.append(class_name)

    # register all the non-grokked, remaining tables (e.g. user tables) 
    register_remaining_tables(registered)
    
    map_tables() 
Exemplo n.º 2
0
    def compute_orm_properties(self, THIS_IS_A_DIRTY_HACK_PROPERTIES_DICT):
        mappedsotype = setobject_type_registry.lookup(self.target_model.klass)
        xref_table_class = None
        sourcetable = setobject_table_registry.lookup_by_class(self.source_model.klass)
        targettable = setobject_table_registry.lookup_by_class(self.target_model.klass)
        if self.cardinality.id == 'MANY_TO_ONE' or \
                self.cardinality.id == 'ONE(FK)_TO_ONE':
            # take primary key on our side
            primaryfk = getattr(sourcetable.c, self.relation.foreignkeycol)
            primaryidentifier = getattr(targettable.c, mappedsotype.get_primary_key_attr_name())
            primaryjoin = (primaryfk == primaryidentifier)
            secondaryjoin = None
        elif self.cardinality.id == 'ONE_TO_MANY' or \
                self.cardinality.id == 'ONE_TO_ONE(FK)':
            # take primary key on other side
            primaryfk = getattr(targettable.c, self.relation.foreignkeycol)
            primaryidentifier = getattr(
                sourcetable.c,
                setobject_type_registry.lookup(self.source_model.klass).get_primary_key_attr_name()
            )
            primaryjoin = (primaryfk == primaryidentifier)
            secondaryjoin = None
        elif self.cardinality.id == 'MANY_TO_MANY':
            # xref! we actually need two clauses here.
            
            # Obtain table class:
            xref_table_class = setobject_table_registry.get_by_table(self.relation.xref_table)
            if xref_table_class is None:
                # Class is not mapped (probably not having a primary key or something like that) -> autoload
                xref_table_class = Table(self.relation.xref_table, metadata, autoload=True, useexisting=True, autoload_with=getUtility(IDbUtility).engine)
            
            # Compose two join clauses
            primaryjoin = (cls.get_primary_key_column() == getattr(xref_table_class.c, self.relation.foreignkeycol))
            secondaryjoin = (mappedsotype.get_primary_key_column() == getattr(xref_table_class.c, self.relation.foreignkeycol2))
        
        # add the obtained setobject to our mapped properties
        if self.cardinality.id == 'MANY_TO_ONE':
            # This mapping should really not happen here and now.
            # Instead, the linkage MUST be persisted into
            # table p2_linkage at save time!

            THIS_IS_A_DIRTY_HACK_PROPERTIES_DICT[self.attr_name] = orm.relation(
                mappedsotype,
                uselist=False,
                cascade=self.cascade,
                back_populates=self.back_populates,
                primaryjoin=primaryjoin,
                post_update=self.post_update
            )
            relationarguments = {
                'uselist' : False,
                'cascade' : self.cascade,
                'back_populates' : self.back_populates,
                'primaryjoin' : primaryjoin,
                'post_update' : self.post_update
            }
        else:
            # the other side has the foreign key, store things as a collection
            
            order_by = None
            collection_class = None
            
            # This is a special case for the spans as they should not be mapped as ordinary
            # dictionary, but rather as an orderable dictionary. This is necessary to retain the insert order
            # as a ordinary dict isn't ordered. Consider this to be implemented in a more generic way if this
            # use case is occuring for user relations as well.
            if self.attr_name == 'spans' and self.source_model.klass == 'WidgetType':
                collection_class=SpanCollectionClass
                span_table = setobject_table_registry.lookup_by_table('p2_span')
                order_by=span_table.c.order
            
            # This is another special case to ensure the widgets being tab ordered
            if self.attr_name == 'widgets' and self.source_model.klass == 'FormType':
                collection_class = WidgetCollectionClass
                widget_table = setobject_table_registry.lookup_by_table('p2_widget')
                order_by=widget_table.c.tab_order
            
            # Get collection class
            if collection_class == None:
                if self.ref_key is None:
                    collection_class = column_mapped_collection(mappedsotype.get_primary_key_column())
                else:
                    mapped_column = mappedsotype.get_column(self.ref_key)
                    collection_class = column_mapped_collection(mapped_column)
            
            # Compute arguments:
            relationarguments = {
                'back_populates' : self.back_populates,
                'collection_class' : collection_class,
                'uselist' : True,
                'primaryjoin': primaryjoin,
                'cascade' : self.cascade,
                'post_update' : self.post_update
                }
            if order_by is not None:
                relationarguments['order_by'] = order_by
        
        # Set xref table if we got one
        if xref_table_class is not None:
            relationarguments['secondary'] = xref_table_class
            if secondaryjoin is not None:
                relationarguments['secondaryjoin'] = secondaryjoin
        
        return relationarguments