Учитывая декларативный класс SQLAlchemy, как я могу программно получить список его объектов Column, которые являются первичными ключами? - PullRequest
3 голосов
/ 22 февраля 2012

Скажем, у меня есть класс в SQLAlchemy, как

class Note(Base):
    __tablename__ = 'notes'
    slug = Column('short_title', String, primary_key=True)
    date = Column('day', Date, primary_key=True)
    contents = Column(Text, nullable=True)

Учитывая только ссылку на класс Note, как функция может построить список ['Note.slug', 'Note.date'], основанный на том, что они составляют первичный ключ соответствующей таблицы?

Кроме того, есть ли способ фильтрации атрибутов класса на основе свойств столбца? (например, обнуляемый, тип, уникальность, членство в индексе и т. д.)

Ответы [ 3 ]

4 голосов
/ 22 мая 2013

это даст вам список имен столбцов, которые являются primary_keys:

from sqlalchemy.orm import class_mapper

primary_keys = [key.name for key in class_mapper(Note).primary_key]
4 голосов
/ 23 февраля 2012

Попробуйте найти основные поля.

from sqlalchemy import create_engine

engine = create_engine('sqlite:///:memory:', echo=True)

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Date, Text
from sqlalchemy.orm.attributes import InstrumentedAttribute


Base = declarative_base()

class Note(Base):
    __tablename__ = 'notes'
    slug = Column('short_title', String, primary_key=True)
    date = Column('day', Date, primary_key=True)
    contents = Column(Text, nullable=True)

if __name__ == '__main__':
    import inspect
    predicate = lambda x: isinstance(x, InstrumentedAttribute)

    fields = inspect.getmembers(Note, predicate=predicate)

    fields_vars = [vars(y.property.columns[0]) for x,y in fields]

    primary_fields = [x['name'] for x in fields_vars if x['primary_key']]

    print "All Fields :", fields_vars

    print "Primary Fields :", primary_fields

Таким образом, вы можете найти любой тип полей из вашей модели.

3 голосов
/ 02 марта 2012

Не совсем то, что нужно, но немного более короткий вариант, который использует только внутри информации:

from sqlalchemy import create_engine

engine = create_engine('sqlite:///:memory:', echo=True)

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Date, Text

Base = declarative_base()

class Note(Base):
    __tablename__ = 'notes'
    slug = Column('short_title', String, primary_key=True)
    date = Column('day', Date, primary_key=True)
    contents = Column(Text, nullable=True)

if __name__ == '__main__':
    print [(i.name, i.primary_key) for i in Note.__table__.columns]

Это дает нам следующий результат:

[('short_title', True), ('day', True), ('contents', False)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...