Exemplo n.º 1
0
 def DBCOOK_dbname( asocklas):
     #this sees forward-resolved
     this_side_klas,  this_side_attr  = asocklas.get_link_info( 'left',  short=True)
     other_side_klas, other_side_attr = asocklas.get_link_info( 'right', short=True)
     r = '_'.join( x for x in (
             asocklas.HIDDEN_NAME_PREFIX,
             table_namer( this_side_klas, short=True ), this_side_attr,
             '2',
             table_namer( other_side_klas, short=True), other_side_attr
         ) if x)
     return r
Exemplo n.º 2
0
 def DBCOOK_dbname(asocklas):
     #this sees forward-resolved
     this_side_klas, this_side_attr = asocklas.get_link_info(
         'left', short=True)
     other_side_klas, other_side_attr = asocklas.get_link_info(
         'right', short=True)
     r = '_'.join(
         x
         for x in (asocklas.HIDDEN_NAME_PREFIX,
                   table_namer(this_side_klas, short=True),
                   this_side_attr, '2',
                   table_namer(other_side_klas, short=True),
                   other_side_attr) if x)
     return r
Exemplo n.º 3
0
def make_table( klas, metadata, builder, **kargs):
    dbg = 'table' in config.debug
    if dbg: print '\n'+'make_table for:', klas.__name__, kargs
    columns = make_table_columns( klas, builder, **kargs)
    name = table_namer( klas)
    t = sa.Table( name, metadata, *columns )
    if dbg: print repr(t)
    return t
Exemplo n.º 4
0
def make_klas_selectable( mapcontext, klas, tables, test =False):
    '''construct the selectable for extracting objects of
    exactly this klas (and not subklasses);
    for all cases of inheritance-represention (concrete,multitable,single)
    '''
    joined_tables = []
    base_klas = klas
    while True:     #go toward base, stop on first concrete-table
        tbase = tables[ base_klas]
        joined_tables.insert( 0, tbase)
        base_klas, inheritype = mapcontext.base4table_inheritance( base_klas)
        if inheritype == table_inheritance_types.CONCRETE:
            break

    j = joined_tables[0]
    if test:
        jtest = joined_tables[0].name

    if len(joined_tables)>1:
        for t in joined_tables[1:]:
            # explicit, allow other relations via id
            other_table = isinstance( j, sqlalchemy.Table) and j or j.right
            j = sa.join( j, t,
                    column4ID( t) == column4ID( other_table) )
            if test:
                jtest += '.join( '+t.name
                #jtest += ' /on '+ other_table.name +'.id'
                jtest += ' )'

    jfiltered = exprfilter = None
    is_non_concrete_inherited = mapcontext.is_direct_inherited_non_concrete( klas)
    if is_non_concrete_inherited:   # -> нуждае се от филтър по тип; correlate=False и в двата случая
        #X.select(X.atype==X)
        exprfilter = column4type( tbase) == klas.__name__
        if isinstance( j, sqlalchemy.sql.Join): #if len(joined_tables)>1
            jfiltered = j.select( exprfilter, fold_equivalents=True)
        else:
            jfiltered = j.select( exprfilter)

        jfiltered = jfiltered.alias( 'bz4' + table_namer( klas) )
        if test:
            jtest += '.select( '+tbase.name+ '.typ=='+klas.__name__ + ' )'
    else:
        jfiltered = j

    if test: j = jtest
    return dict( filtered= jfiltered, plain= j,
                    filter= exprfilter,   #fold_equivalents=True) XXX???
                    base_table= tbase,
                )
Exemplo n.º 5
0
def make_table_column4id_fk( column_name, other_klas,
                            type =None, fk_kargs ={}, **column_kargs):
    dbg = 'column' in config.debug or 'relation' in config.debug
    if dbg: print 'make_table_column4id_fk', column_name, '->', other_klas.__name__
    assert type
    assert other_klas
    fk = sa.ForeignKey(
                table_namer( other_klas)+'.'+column4ID.name,
                **fk_kargs
            )
    if dbg: print '  foreignkey', column_name, column_kargs, fk, fk_kargs

    #if column_kargs.get( 'nullable'): column_kargs['autoincrement'] = False
    c = sa.Column( column_name,
                type,
                fk,     #must be in *args
                autoincrement= False,       #meaningless, regardless nullable or not
                **column_kargs  #typemap_kargs
            )
    if dbg: print '    = ', repr(c)
    return c
Exemplo n.º 6
0
def resolve_assoc_hidden(builder, klasi):
    dbg = 'assoc' in config.debug or 'relation' in config.debug
    mapcontext = builder.mapcontext
    news = {}
    for k, klas in klasi.iteritems():
        for attr, rel_typ, nonmappable_origin in sorted(
                mapcontext.iter_attr(klas,
                                     collections=True,
                                     attr_base_klas=_AssocAutomatic,
                                     local=True,
                                     denote_nonmappable_origin=True,
                                     dbg=dbg),
                key=lambda (a, rel_typ, nmo): (rel_typ.variant_of, nmo, a)):
            rel_typ.name = attr
            attr_short = getattr(rel_typ, 'name_short', None)
            other_side_klas = rel_typ.assoc_klas
            Assoc = rel_typ.assoc_base
            other_side_attr = rel_typ.backrefname
            if dbg:
                print 'assoc_auto: ', klas, '.' + attr, '<->', rel_typ,
                if rel_typ.synonym_by:
                    print 'synonym_by:' + rel_typ.synonym_by,
                if rel_typ.variant_of:
                    print 'variant_of:' + rel_typ.variant_of,
                print

            mapbase = mapcontext.base_klas
            if not issubclass(Assoc, mapbase):
                metabase = getattr(Assoc, '__metaclass__', None)
                if not metabase:
                    metabase = getattr(mapbase, '__metaclass__', None)
                if not metabase: metabase = type

                class meta(metabase):
                    def __new__(meta, name, bases, adict):
                        bases = (mapbase, ) + bases
                        return metabase.__new__(meta, name, bases, adict)
            else:

                meta = None

            backref_kargs = dict(
                name=attr,
                lazy=True,
                uselist=True,
                #collection_class= Assoc._CollectionFactory,
            )

            class AssocHidden(Assoc):
                DBCOOK_automatic = True
                if meta: __metaclass__ = meta
                DBCOOK_hidden = rel_typ.hidden
                if rel_typ.indexes:
                    DBCOOK_indexes = list(
                        Assoc.DBCOOK_indexes) + 'left right'.split()
                left = Assoc.Link(
                    klas,
                    attr=attr,
                    nullable=False,
                    attr_short=attr_short,
                    #XXX TODO right now, explicit-automatic-assoc will get BOTH A.relation() and assoc.reference
                    # must be 1 only, with backref XXX
                    backref=not rel_typ.hidden and backref_kargs,
                )
                right = Assoc.Link(other_side_klas,
                                   attr=other_side_attr,
                                   nullable=False)
                if rel_typ.variant_of:
                    _DBCOOK_variant_of = getattr(
                        klas, rel_typ.variant_of
                    )  #ok for cloned because of nonmappable_origin
                if rel_typ.dbname:
                    DBCOOK_dbname = rel_typ.dbname
                else:

                    @classmethod
                    def DBCOOK_dbname(asocklas):
                        #this sees forward-resolved
                        this_side_klas, this_side_attr = asocklas.get_link_info(
                            'left', short=True)
                        other_side_klas, other_side_attr = asocklas.get_link_info(
                            'right', short=True)
                        r = '_'.join(
                            x
                            for x in (asocklas.HIDDEN_NAME_PREFIX,
                                      table_namer(this_side_klas, short=True),
                                      this_side_attr, '2',
                                      table_namer(other_side_klas, short=True),
                                      other_side_attr) if x)
                        return r

            backref_kargs['collection_class'] = AssocHidden._CollectionFactory

            #TODO test

            if nonmappable_origin:
                if dbg: print ' inherited from nonmappable base, clone'
                rel_typ = rel_typ.copy()
                setattr(klas, attr, rel_typ)
            rel_typ.assoc_klas = assoc_klas = AssocHidden

            #change __name__ - see __name__DYNAMIC
            klasname = '_'.join(x for x in (
                Assoc.HIDDEN_NAME_PREFIX,
                table_namer(klas, short=True),
                attr,  #do not use attr_short
                '2',
                isinstance(other_side_klas, str) and other_side_klas
                or table_namer(other_side_klas, short=True),
                other_side_attr) if x)
            assoc_klas.__name__ = klasname

            #self-add to mappable klasi
            news[klasname] = assoc_klas
    klasi.update(news)
Exemplo n.º 7
0
def resolve_assoc_hidden( builder, klasi):
    dbg = 'assoc' in config.debug or 'relation' in config.debug
    mapcontext = builder.mapcontext
    news = {}
    for k,klas in klasi.iteritems():
        for attr, rel_typ, nonmappable_origin in sorted( mapcontext.iter_attr( klas,
                                                    collections=True,
                                                    attr_base_klas= _AssocAutomatic,
                                                    local= True,
                                                    denote_nonmappable_origin= True,
                                                    dbg=dbg ),
                                                key= lambda (a,rel_typ,nmo): (rel_typ.variant_of,nmo,a) ):
            rel_typ.name = attr
            attr_short = getattr( rel_typ, 'name_short', None)
            other_side_klas = rel_typ.assoc_klas
            Assoc = rel_typ.assoc_base
            other_side_attr = rel_typ.backrefname
            if dbg:
                print 'assoc_auto: ', klas, '.'+attr, '<->', rel_typ,
                if rel_typ.synonym_by: print 'synonym_by:'+rel_typ.synonym_by,
                if rel_typ.variant_of: print 'variant_of:'+rel_typ.variant_of,
                print

            mapbase = mapcontext.base_klas
            if not issubclass( Assoc, mapbase):
                metabase = getattr( Assoc, '__metaclass__', None)
                if not metabase: metabase = getattr( mapbase, '__metaclass__', None)
                if not metabase: metabase = type
                class meta( metabase):
                    def __new__( meta, name, bases, adict):
                        bases = (mapbase,) + bases
                        return metabase.__new__( meta, name, bases, adict)
            else: meta = None


            backref_kargs = dict( name= attr,
                                lazy= True,
                                uselist= True,
                                #collection_class= Assoc._CollectionFactory,
                            )

            class AssocHidden( Assoc):
                DBCOOK_automatic = True
                if meta: __metaclass__ = meta
                DBCOOK_hidden = rel_typ.hidden
                if rel_typ.indexes:
                    DBCOOK_indexes = list(Assoc.DBCOOK_indexes) + 'left right'.split()
                left  = Assoc.Link( klas, attr= attr, nullable=False, attr_short= attr_short,
                        #XXX TODO right now, explicit-automatic-assoc will get BOTH A.relation() and assoc.reference
                        # must be 1 only, with backref XXX
                        backref= not rel_typ.hidden and backref_kargs,
                    )
                right = Assoc.Link( other_side_klas, attr= other_side_attr, nullable=False)
                if rel_typ.variant_of:
                    _DBCOOK_variant_of = getattr( klas, rel_typ.variant_of)     #ok for cloned because of nonmappable_origin
                if rel_typ.dbname:
                    DBCOOK_dbname = rel_typ.dbname
                else:
                    @classmethod
                    def DBCOOK_dbname( asocklas):
                        #this sees forward-resolved
                        this_side_klas,  this_side_attr  = asocklas.get_link_info( 'left',  short=True)
                        other_side_klas, other_side_attr = asocklas.get_link_info( 'right', short=True)
                        r = '_'.join( x for x in (
                                asocklas.HIDDEN_NAME_PREFIX,
                                table_namer( this_side_klas, short=True ), this_side_attr,
                                '2',
                                table_namer( other_side_klas, short=True), other_side_attr
                            ) if x)
                        return r

            backref_kargs[ 'collection_class'] = AssocHidden._CollectionFactory

            #TODO test

            if nonmappable_origin:
                if dbg: print ' inherited from nonmappable base, clone'
                rel_typ = rel_typ.copy()
                setattr( klas, attr, rel_typ)
            rel_typ.assoc_klas = assoc_klas = AssocHidden

            #change __name__ - see __name__DYNAMIC
            klasname = '_'.join( x for x in (
                Assoc.HIDDEN_NAME_PREFIX,
                table_namer( klas, short=True), attr,       #do not use attr_short
                '2',
                isinstance( other_side_klas, str) and other_side_klas or table_namer( other_side_klas, short=True),
                other_side_attr ) if x)
            assoc_klas.__name__ = klasname

            #self-add to mappable klasi
            news[ klasname ] = assoc_klas
    klasi.update( news)
Exemplo n.º 8
0
 def dbname( klas):
     import config   #XXX ~hack
     return config.table_namer( klas)
Exemplo n.º 9
0
 def dbname(klas):
     import config  #XXX ~hack
     return config.table_namer(klas)