77 from StringIO import StringIO
88
99import sqlalchemy
10- from sqlalchemy import exc
10+ from sqlalchemy import exc , and_
1111from sqlalchemy import MetaData , ForeignKeyConstraint
1212from sqlalchemy .ext .declarative import declarative_base
1313try :
4040handler .setFormatter (formatter )
4141log .addHandler (handler )
4242
43- def fk_repr (self ):
44- import ipdb ; ipdb .set_trace ()
45-
4643def by_name (a , b ):
4744 if a .name > b .name :
4845 return 1
@@ -232,14 +229,17 @@ def _relation_repr(cls, rel):
232229 target = target .__name__
233230 primaryjoin = ''
234231 lookup = mtl ()
235- if rel .primaryjoin is not None :
232+ if rel .primaryjoin is not None and hasattr ( rel . primaryjoin , 'right' ) :
236233 right_lookup = lookup .get (rel .primaryjoin .right .table .name , '%s.c' % rel .primaryjoin .right .table .name )
237234 left_lookup = lookup .get (rel .primaryjoin .left .table .name , '%s.c' % rel .primaryjoin .left .table .name )
238235
239236 primaryjoin = ", primaryjoin='%s.%s==%s.%s'" % (left_lookup ,
240237 rel .primaryjoin .left .name ,
241238 right_lookup ,
242239 rel .primaryjoin .right .name )
240+ elif hasattr (rel , '_as_string' ):
241+ primaryjoin = ', primaryjoin="%s"' % rel ._as_string
242+
243243 secondary = ''
244244 secondaryjoin = ''
245245 if rel .secondary is not None :
@@ -271,11 +271,11 @@ def __repr__(cls):
271271 else :
272272 s += " __tablename__ = '%s'\n \n " % table_name
273273 if hasattr (cls , '__table_args__' ):
274- if cls .__table_args__ [0 ]:
275- for fkc in cls .__table_args__ [0 ]:
276- fkc .__class__ .__repr__ = foreignkeyconstraint_repr
277- break
278- s += " __table_args__ = (%s, %s) \n \n " % ( cls .__table_args__ [ 0 ], cls . __table_args__ [ 1 ])
274+ # if cls.__table_args__[0]:
275+ # for fkc in cls.__table_args__[0]:
276+ # fkc.__class__.__repr__ = foreignkeyconstraint_repr
277+ # break
278+ s += " __table_args__ = %s \n \n " % cls .__table_args__
279279 s += " #column definitions\n "
280280 for column in sorted (cls .__table__ .c , by_name ):
281281 s += " %s = %s\n " % (column .name , column_repr (column ))
@@ -297,7 +297,9 @@ def __repr__(cls):
297297
298298 #hack the class to have the right classname
299299 Temporal .__name__ = model_name
300- Temporal .__table_args__ = ([], {})
300+
301+ #set up some blank table args
302+ Temporal .__table_args__ = {}
301303
302304 #add in the schema
303305 if self .config .schema :
@@ -322,18 +324,33 @@ def __repr__(cls):
322324
323325 setattr (Temporal , related_table .name , _deferred_relationship (Temporal , rel ))
324326
325- #add in composite foreign_keys
326- for fk in self .get_composite_foreign_keys (table ):
327- log .info (' Adding composite FKs for: %s' % [item .column .name for item in fk ])
328- # import ipdb; ipdb.set_trace()
329- Temporal .__table_args__ [0 ].append (ForeignKeyConstraint ([k .parent .name for k in fk ],
330- ["%s.%s" % (k .column .table .name , k .column .name ) for k in fk ],
331- use_alter = False ,
332- table = table
333- ))
334-
335- #remove foreign keys from associated columns (they are likely wrong)
327+ #add in the relations for the composites
328+ for constraint in table .constraints :
329+ if isinstance (constraint , ForeignKeyConstraint ):
330+ if len (constraint .elements ) > 1 :
331+ related_table = constraint .elements [0 ].column .table
332+ related_classname = singular (name2label (related_table .name , related_table .schema ))
333+
334+ print "and_(%s)" % ', ' .join (["%s.%s==%s.%s" % (model_name ,
335+ k .parent .name ,
336+ related_classname ,
337+ k .column .name )
338+ for k in constraint .elements ])
339+
340+ primary_join = "and_(%s)" % ', ' .join (["%s.%s==%s.%s" % (model_name ,
341+ k .parent .name ,
342+ related_classname ,
343+ k .column .name )
344+ for k in constraint .elements ])
345+ rel = relation (related_classname ,
346+ primaryjoin = primary_join
347+ # foreign_keys=[k.parent for k in constraint.elements]
348+ )
349+
350+ rel ._as_string = primary_join
351+ setattr (Temporal , related_table .name , rel ) # _deferred_relationship(Temporal, rel))
336352
353+
337354 #add in many-to-many relations
338355 for join_table in self .get_related_many_to_many_tables (table .name ):
339356
@@ -350,7 +367,6 @@ def __repr__(cls):
350367 if related_table not in self .tables :
351368 continue
352369 log .info (' Adding <secondary> foreign key(%s) for:%s' % (key , related_table .name ))
353- # import ipdb; ipdb.set_trace()
354370 setattr (Temporal , plural (related_table .name ), _deferred_relationship (Temporal ,
355371 relation (singular (name2label (related_table .name ,
356372 related_table .schema )),
0 commit comments