Woah, I may have wondered that when I thought on attaching an event, but
yes I was thinking the opposite when using it like the underscores in
the table name level.
I can't see how this was easier - lol - but it makes sense to me :)
Thanks Mike! This should get into the SA examples or recipes!
Best regards,
Richard.
On 06/07/2013 03:13 PM, Michael Bayer wrote:
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
<[email protected] <mailto:[email protected]>> 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
<[email protected] <mailto:[email protected]>> 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 [email protected]
<mailto:[email protected]>.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
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 [email protected].
To post to this group, send email to [email protected].
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 [email protected]
<mailto:[email protected]>.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
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 [email protected].
To post to this group, send email to [email protected].
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.