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.


Reply via email to