SQLAlchemy самоанализ декларативных классов - PullRequest
7 голосов
/ 01 августа 2010

Я пишу небольшую оболочку sqlalchemy для экспорта данных из базы данных MySQL с некоторыми легкими преобразованиями данных - в основном меняя имена полей. Мой текущий скрипт работает нормально, но требует, чтобы я по существу описал мою модель дважды - один раз в объявлении класса и один раз в виде списка имен полей для повторения.

Я пытаюсь выяснить, как использовать самоанализ для определения свойств объектов-строк, которые являются методами доступа к столбцам. Следующее работает почти идеально:

for attr, value in self.__class__.__dict__.iteritems():
    if isinstance(value, sqlalchemy.orm.attributes.InstrumentedAttribute):
        self.__class__._columns.append(attr)

за исключением того, что мои методы доступа ко многим также являются экземплярами sqlalchemy.orm.attributes.InstrumentedAttribute, и мне нужно их пропустить. Есть ли какой-нибудь способ провести различие между ними во время проверки словаря классов?

Большая часть документации, которую я нахожу по самоанализу sqlalchemy, включает просмотр metadata.table, но, поскольку я переименовываю столбцы, эти данные нетривиально сопоставимы.

Ответы [ 3 ]

7 голосов
/ 01 августа 2010

Mapper каждого сопоставленного объекта имеет атрибут columns со всеми определениями столбцов.Например, если у вас есть декларативный класс User, вы можете получить доступ к мапперу с помощью User.__mapper__, а столбцы с:

list(User.__mapper__.columns)

Каждый столбец имеет несколько атрибутов, включая name (которые могут бытьтакой же, как сопоставленный атрибут с именами key), nullable, unique и т. д. *

1 голос
/ 31 августа 2012

Экземпляр InstrumentedAttribute имеет атрибут с именем impl, который на практике является ScalarAttributeImpl, ScalarObjectAttributeImpl или CollectionAttributeImpl.

Я не уверен, насколько это хрупко, но я просто проверяю, какая именно, чтобы определить, будет ли экземпляр в конечном итоге возвращать список или один объект.

1 голос
/ 01 августа 2010

Я все еще хотел бы увидеть ответ на этот вопрос, но я обошел его, изменив имена участников доступа (например, «_otherentity» вместо «otherentity») и затем отфильтровав имя. Хорошо работает для моих целей.

...