在将控件传递给
DeclarativeMeta
. 另一种方法是在
before_parent_attach
的事件处理程序
Column
,但与使用特定声明性基的映射类中的列相比,这将全局影响所有列。
from sqlalchemy.ext.declarative.api import DeclarativeMeta
from sqlalchemy import Column
class RenamingDeclarativeMeta(DeclarativeMeta):
def __init__(cls, name, bases, namespace):
_rename_declared_columns(namespace)
super().__init__(name, bases, namespace)
def __setattr__(cls, key, value):
if isinstance(value, Column):
_undefer_column_name_only(key, value)
super().__setattr__(key, value)
def to_camelcase(s):
return ''.join([w.title() for w in s.split('_')])
def _undefer_column_name_only(key, column):
if column.name is None:
column.name = to_camelcase(key)
def _rename_declared_columns(namespace):
for key, attr in namespace.items():
if isinstance(attr, Column):
_undefer_column_name_only(key, attr)
ColumnProperty
和
CompositeProperty
metaclass
到
declarative_base()
:
In [2]: from sqlalchemy.ext.declarative import declarative_base
In [3]: Base = declarative_base(metaclass=RenamingDeclarativeMeta)
In [4]: from sqlalchemy import Column, Integer
In [5]: class Foo(Base):
...: __tablename__ = 'foo'
...: id = Column(Integer, primary_key=True)
...: bar_baz_1 = Column(Integer, nullable=False)
...:
In [6]: Foo.id
Out[6]: <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x7ffb7f770e60>
In [7]: Foo.bar_baz_1
Out[7]: <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x7ffb7dc47200>
In [8]: list(Foo.__table__.columns)
Out[8]:
[Column('Id', Integer(), table=<foo>, key='id', primary_key=True, nullable=False),
Column('BarBaz1', Integer(), table=<foo>, key='bar_baz_1', nullable=False)]
另一种方法是全局重命名附加到的所有列
Table
对象使用
event API
from sqlalchemy import event
@event.listens_for(Column, 'before_parent_attach')
def receive_column_before_table_attach(column, table):
# As dumb as it gets. Blindly modifies all columns.
column.name = to_camelcase(column.name)
这个有一个
专业