The name assigned to the class and the name given to the Column when it emits CREATE TABLE are two different things.
The "name" is what you'll see in CREATE TABLE, easy enough, "return Column('id', ...)"
As far as the name assigned to the class, in classical mappings the "key" of the Column is used, and it might be nice if declarative looked at column.key in this case, however it doesn't. There is a way this could probably be hacked on, by creating a custom __mapper__ classmethod and converting all the Columns with custom .keys to be mapped with that name. a little ugly, though.
of course the blunt tool that works in all cases is the custom metaclass, but that approach is fairly tedious and is probably a lot uglier than just the __mapper__ hack above.
Another way that is a little verbose but is the least intrusive is to just use more @declared_attrs.
in 0.8, @declared_attr can be specified on a non-mixin, so this works there:
class A(BaseModel, Base):
__tablename__ = "a"
@declared_attr
def pk(self):
return None
@declared_attr
def id(self):
return BaseModel.pk
if 0.7, another mixin can do it:
class SubBaseModel(BaseModel):
@declared_attr
def pk(self):
return None
@declared_attr
def id(self):
return BaseModel.pk
class A(SubBaseModel, Base):
__tablename__ = "a"
i can show you the __mapper__ hack if that's not good enough.