OK, the prefix is on the mapped attribute name, not the column. So Language(_language = 'foo').
Guess you're looking for the opposite, huh. This gets more weird but this should work, the main difficulty is limiting the columns being altered to just those within a certain class hierarchy, if you wanted to do it based on "table.name.startswith('__')" that would be much simpler: from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import event Base = declarative_base() @event.listens_for(Column, "before_parent_attach") def attach(col, table, **kw): if table.name in prefix_tables: # the trick here is that "col.key" remains # without the underscore col.name = "_" + col.name prefix_tables = set() class PrefixStuff(object): # need to use a metaclass here because we have no event # that will give you the __tablename__ + Language class # before the Table is actually created class __metaclass__(type(Base)): def __init__(self, classname, bases, dict_): prefix_tables.add(dict_.get('__tablename__')) if classname == 'PrefixStuff': return type.__init__(self, classname, bases, dict_) else: return type(Base).__init__(self, classname, bases, dict_) class Language(PrefixStuff, Base): __tablename__ = 'language' language_id = Column(Integer, primary_key=True) language = Column(String(5), unique=True, default='undef') e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) sess = Session(e) sess.add(Language(language='asdf')) sess.commit() On Jun 7, 2013, at 1:40 PM, Richard Gerd Kuesters <rich...@humantech.com.br> wrote: > Thank you Mike! > > That brings me to another question: > > Let's say I have created a simple table (well, I have): > > class Language(Base): > language_id = Column(Integer, Sequence('language_id_seq', optional=True), > primary_key=True) > language = Column(String(5), unique=True, default='undef') > > The problem is (using pdb): > > (Pdb) lang = Language(language='test') > (Pdb) lang > <Language(language='test')> > (Pdb) dir(lang) > ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', > '__getattribute__', '__hash__', '__init__', '__mapper__', '__mapper_cls__', > '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', > '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__table__', > '__tablename__', '__weakref__', '_cls_id', '_decl_class_registry', '_has', > '_language', '_language_id', '_sa_class_manager', '_sa_instance_state', > 'id_', 'language', 'language_id', 'metadata', 't'] > (Pdb) session.add(lang) > (Pdb) session.commit() > (Pdb) lang2 = Language(language='foo') > (Pdb) session.add(lang2) > (Pdb) session.commit() > *** IntegrityError: (IntegrityError) column language is not unique u'INSERT > INTO ht__language (language) VALUES (?)' ('undef',) > (Pdb) session.rollback() > (Pdb) session.query(Language).all() > [<Language(language='test')>] > (Pdb) lang2 = Language() > (Pdb) lang2.language = 'foo' > (Pdb) session.add(lang2) > (Pdb) session.commit() > *** IntegrityError: (IntegrityError) column language is not unique u'INSERT > INTO ht__language (language) VALUES (?)' ('undef',) > (Pdb) session.rollback() > (Pdb) lang2 = Language() > (Pdb) lang2._language = 'foo' > (Pdb) session.add(lang2) > (Pdb) session.commit() > (Pdb) session.query(Language).all() > [<Language()>, <Language(language='test')>] > > If I change the Language class to this: > > class Language(Base): > language_id = Column(Integer, Sequence('language_id_seq', optional=True), > primary_key=True) > language = Column('language', String(5), unique=True, default='undef') > > The same happens. Curiously: > > (Pdb) session.query(Language).all() > [<Language()>, <Language(language='test')>] > (Pdb) map(lambda a: a._language, session.query(Language).all()) > [u'foo', u'undef'] > > Is there a problem using this mapper configuration with declarative bases? > > Cheers, > Richard. > > > > On 06/07/2013 11:46 AM, Michael Bayer wrote: >> >> On Jun 7, 2013, at 9:31 AM, Richard Gerd Kuesters <rich...@humantech.com.br> >> wrote: >> >>> Hi all! >>> >>> I'm refactoring a database schema but I need it to mantain reverse >>> compatibility with older versions of our software - using views. >>> >>> But, to avoid confusion to other developers, new tables have two >>> underscores as a prefix, like: >>> >>> >>> class Base(object): >>> >>> @declared_attr >>> def __tablename__(cls): >>> return "__%s" % to_python_case(cls.__name__) >>> >>> >>> Now I want to add column prefixes too. I know I can append to this Base >>> object: >>> >>> __mapper_args__ = dict( >>> column_prefix='_' >>> ) >>> >>> But, when I inherit this new base on classes that I need to use >>> __mapper_args__, column names probably won't have prefixes. Any ideas, >>> perhaps an event listener to prepend the underscore into *all* column names? >> >> one idea is you can intercept how mapper() is called by declarative by >> overriding __mapper_cls__, like: >> >> @classmethod >> def __mapper_cls__(cls, *args, **kw): >> kw['column_prefix'] = '_' >> return mapper(*args, **kw) >> >> >> >> >> >>> >>> >>> Cheers, >>> Richard. >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "sqlalchemy" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to sqlalchemy+unsubscr...@googlegroups.com. >>> To post to this group, send email to sqlalchemy@googlegroups.com. >>> Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. >>> For more options, visit https://groups.google.com/groups/opt_out. >>> >>> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "sqlalchemy" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to sqlalchemy+unsubscr...@googlegroups.com. >> To post to this group, send email to sqlalchemy@googlegroups.com. >> Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. >> For more options, visit https://groups.google.com/groups/opt_out. >> >> > > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.