On Jan 5, 2013, at 7:42 AM, Alexander Jacob wrote: > @compiles(i18NColumnClause) > def compile_i18n_column_clause(element, compiler, **kw): > return '%s_%s' % (element.name, GLOBAL_LANGUAGE) > > # custom type > class i18NType(sqlalchemy.types.TypeDecorator): > impl = sqlalchemy.types.Unicode > def column_expression(self, colexpr): > return i18NColumnClause(colexpr) > > # test class for custom type > class Country(Base): > > __tablename__ = 'country' > id = Column(Integer, primary_key=True) > iso2 = Column(String(2)) > name = Column(i18NType(64)) > > def __repr__(self): > return "<Country(%d/%s/%s)>" % (self.id, self.iso2, self.name) >
Interesting approach with the column_expression(), though that seems like it would circumvent the labeling behavior of the compiler and cause more complex expressions to fail. The INSERT case might work if you also implemented bind_expression() but I'm not sure if that approach overall doesn't break too much of the existing compilation functionality. A more direct route with @compiles would be to compile Column, but still tricky, in particular that the compilation process for a Column is very involved. At the very least, for that to work it would have to be like this: class i18NColumn(Column): # note it has to be Column, not ColumnClause pass @compiles(i18NColumn) def compile(element, compiler, **kw): text = compile.visit_column(element, **kw) text = text.replace(element.name, '%s_%s' %(element.name, GLOBAL_LANGUAGE)) return text so that existing labeling rules are not circumvented. but even that I'm not 100% sure might not have some gotchas. Another variant on this would be to use the before_cursor_execute event to just do a search and replace on the SQL statement before it's passed to the DBAPI, I sometimes recommend that as well. Giving the "fake" column a name that clearly indicates internationalization, like Column("name_<i18N>"), is a good way to give a statement filter a clear path to where those names would go. If you need this translation behavior everywhere, that might be the best approach. Though here, there's a less intrusive way to get this behavior if ORM level is all you need which is by using hybrids: class Country(Base): # ... name_de = Column(String) name_en = Column(String) @hybrid_property def name(self): return getattr(self, "name_%s" % GLOBAL_LANGUAGE) @name.setter def name(self, value): setattr(self, "name_%s" % GLOBAL_LANGUAGE, value) the above can be generalized: def make_hybrid(name): @hybrid_property def name_attr(self): return getattr(self, "%s_%s" % (name, GLOBAL_LANGUAGE)) @name_attr.setter def name_attr(self, value): setattr(self, "%s_%s" % (name, GLOBAL_LANGUAGE), value) name_attr.__name__ = name return name_attr -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.