SQLAlchemy 모델에 정의 된 열 목록을 반복하는 방법을 알아 내려고했습니다. 몇 가지 모델에 직렬화 및 복사 메서드를 작성하기 위해 그것을 원합니다. obj.__dict__
SA 특정 항목이 많이 포함되어 있으므로 반복 할 수 없습니다 .
누구든지 다음에서 id
및 desc
이름을 얻는 방법을 알고 있습니까?
class JobStatus(Base):
__tablename__ = 'jobstatus'
id = Column(Integer, primary_key=True)
desc = Column(Unicode(20))
이 작은 경우에는 다음을 쉽게 만들 수 있습니다.
def logme(self):
return {'id': self.id, 'desc': self.desc}
하지만 dict
(더 큰 개체의 경우) 자동 생성되는 것을 선호합니다 .
답변
다음 기능을 사용할 수 있습니다.
def __unicode__(self):
return "[%s(%s)]" % (self.__class__.__name__, ', '.join('%s=%s' % (k, self.__dict__[k]) for k in sorted(self.__dict__) if '_sa_' != k[:4]))
SA 매직 속성 은 제외 되지만 관계는 제외되지 않습니다. 따라서 기본적으로 종속성, 부모, 자식 등을로드 할 수 있습니다. 이는 확실히 바람직하지 않습니다.
그러나에서 상속 Base
하면 __table__
속성이 있으므로 다음을 수행 할 수 있기 때문에 실제로 훨씬 쉽습니다 .
for c in JobStatus.__table__.columns:
print c
for c in JobStatus.__table__.foreign_keys:
print c
참조 SQLAlchemy의 매핑 개체에서 테이블 속성을 발견하는 방법 비슷한 질문을 -.
Mike 편집 : Mapper.c 및 Mapper.mapped_table 과 같은 함수를 참조하십시오 . 0.8 이상을 사용하는 경우 Mapper.attrs 및 관련 함수 도 참조하십시오 .
Mapper.attrs의 예 :
from sqlalchemy import inspect
mapper = inspect(JobStatus)
for column in mapper.attrs:
print column.key
답변
매퍼에서 정의 된 속성 목록을 가져올 수 있습니다. 귀하의 경우에는 ColumnProperty 객체에만 관심이 있습니다.
from sqlalchemy.orm import class_mapper
import sqlalchemy
def attribute_names(cls):
return [prop.key for prop in class_mapper(cls).iterate_properties
if isinstance(prop, sqlalchemy.orm.ColumnProperty)]
답변
나는 이것이 오래된 질문이라는 것을 알고 있지만 동일한 요구 사항을 발견했으며 미래의 독자에게 대안 솔루션을 제공하고 싶습니다.
조쉬 노트로, 전체 SQL 필드 이름에 의해 반환됩니다 JobStatus.__table__.columns
, 그래서보다는 원래 필드 이름 아이디 , 당신은 얻을 것이다 jobstatus.id . 가능한 한 유용하지 않습니다.
원래 정의 된대로 필드 이름 목록을 얻는 솔루션 _data
은 전체 데이터를 포함하는 열 개체 에서 속성 을 보는 것 입니다. 를 보면 JobStatus.__table__.columns._data
다음과 같습니다.
{'desc': Column('desc', Unicode(length=20), table=<jobstatus>),
'id': Column('id', Integer(), table=<jobstatus>, primary_key=True, nullable=False)}
여기에서 간단 JobStatus.__table__.columns._data.keys()
하고 깔끔한 목록을 제공하는 호출 할 수 있습니다 .
['id', 'desc']
답변
self.__table__.columns
특정 클래스에 정의 된 열만 제공합니다. 즉, 상속 된 열이 없습니다. 모두 필요한 경우 self.__mapper__.columns
. 귀하의 예에서 나는 아마도 다음과 같은 것을 사용할 것입니다.
class JobStatus(Base):
...
def __iter__(self):
values = vars(self)
for attr in self.__mapper__.columns.keys():
if attr in values:
yield attr, values[attr]
def logme(self):
return dict(self)
답변
SQLAlchemy의 선언적 매핑을 사용한다고 가정하면 __mapper__
특성을 사용 하여 클래스 매퍼를 가져올 수 있습니다 . 모든 매핑 된 속성 (관계 포함)을 가져 오려면 :
obj.__mapper__.attrs.keys()
엄격하게 열 이름을 원하면 obj.__mapper__.column_attrs.keys()
. 다른보기에 대해서는 문서를 참조하십시오.
https://docs.sqlalchemy.org/en/latest/orm/mapping_api.html#sqlalchemy.orm.mapper.Mapper.attrs
답변
as_dict
모든 클래스에 대한 메소드 를 얻기 위해 Ants Aasma가Mixin
설명하는 기술을 사용하는 클래스를 사용했습니다 .
class BaseMixin(object):
def as_dict(self):
result = {}
for prop in class_mapper(self.__class__).iterate_properties:
if isinstance(prop, ColumnProperty):
result[prop.key] = getattr(self, prop.key)
return result
그런 다음 수업에서 이렇게 사용하십시오.
class MyClass(BaseMixin, Base):
pass
이렇게하면의 인스턴스에서 다음을 호출 할 수 있습니다 MyClass
.
> myclass = MyClass()
> myclass.as_dict()
도움이 되었기를 바랍니다.
나는 이것으로 조금 더 놀아 보았고 실제로 관련 객체에 대한 링크가 dict
있는 HAL 객체 의 형태로 인스턴스를 렌더링 해야했습니다. 그래서 저는 여기에이 작은 마법을 추가했습니다. 위와 같은 클래스의 모든 속성을 탐색 할 것입니다. 차이점은 Relaionship
속성을 더 깊이 탐색 하고 links
자동으로 생성 할 것입니다.
이것은 단일 기본 키가있는 관계에서만 작동합니다.
from sqlalchemy.orm import class_mapper, ColumnProperty
from functools import reduce
def deepgetattr(obj, attr):
"""Recurses through an attribute chain to get the ultimate value."""
return reduce(getattr, attr.split('.'), obj)
class BaseMixin(object):
def as_dict(self):
IgnoreInstrumented = (
InstrumentedList, InstrumentedDict, InstrumentedSet
)
result = {}
for prop in class_mapper(self.__class__).iterate_properties:
if isinstance(getattr(self, prop.key), IgnoreInstrumented):
# All reverse relations are assigned to each related instances
# we don't need to link these, so we skip
continue
if isinstance(prop, ColumnProperty):
# Add simple property to the dictionary with its value
result[prop.key] = getattr(self, prop.key)
if isinstance(prop, RelationshipProperty):
# Construct links relaions
if 'links' not in result:
result['links'] = {}
# Get value using nested class keys
value = (
deepgetattr(
self, prop.key + "." + prop.mapper.primary_key[0].key
)
)
result['links'][prop.key] = {}
result['links'][prop.key]['href'] = (
"/{}/{}".format(prop.key, value)
)
return result
답변
self.__dict__
키는 속성 이름이고 값은 객체의 값인 dict를 반환합니다.
/! \ 보조 속성 ‘_sa_instance_state’가 있지만 처리 할 수 있습니다. 🙂
