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
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
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
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, )
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
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)
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)
def dbname( klas): import config #XXX ~hack return config.table_namer( klas)
def dbname(klas): import config #XXX ~hack return config.table_namer(klas)