Saya telah mencoba mencari cara untuk mengulang daftar kolom yang ditentukan dalam model SQLAlchemy. Saya menginginkannya untuk menulis beberapa serialisasi dan metode penyalinan ke beberapa model. Saya tidak bisa hanya mengulang obj.__dict__
karena mengandung banyak item spesifik SA.
Adakah yang tahu cara mendapatkan nama id
dan desc
dari berikut ini?
class JobStatus(Base):
__tablename__ = 'jobstatus'
id = Column(Integer, primary_key=True)
desc = Column(Unicode(20))
Dalam kasus kecil ini saya dapat dengan mudah membuat:
def logme(self):
return {'id': self.id, 'desc': self.desc}
tapi saya lebih suka sesuatu yang otomatis menghasilkan dict
(untuk objek yang lebih besar).
sumber
__table__.columns
akan memberi Anda nama kolom SQL, bukan nama atribut yang Anda gunakan dalam definisi ORM Anda (jika keduanya berbeda).'_sa_' != k[:4]
untuk mengubah kenot k.startswith('_sa_')
?inspect(JobStatus).columns.keys()
Anda bisa mendapatkan daftar properti yang ditentukan dari pembuat peta. Untuk kasus Anda, Anda hanya tertarik pada objek ColumnProperty.
sumber
class_mapper
perlu diimpor darisqlalchemy.orm
inspect()
, yang mengembalikan objek mapper yang sama persis denganclass_mapper()
. docs.sqlalchemy.org/en/latest/core/inspection.htmlSaya menyadari bahwa ini adalah pertanyaan lama, tetapi saya baru saja menemukan persyaratan yang sama dan ingin menawarkan solusi alternatif bagi pembaca di masa mendatang.
Seperti yang Josh catat, nama field SQL lengkap akan dikembalikan
JobStatus.__table__.columns
, jadi daripada id nama field asli , Anda akan mendapatkan jobstatus.id . Tidak berguna seperti yang seharusnya.Solusi untuk mendapatkan daftar nama bidang seperti yang awalnya ditentukan adalah dengan melihat
_data
atribut pada objek kolom, yang berisi data lengkap. Jika kita lihatJobStatus.__table__.columns._data
, tampilannya seperti ini:Dari sini Anda cukup memanggil
JobStatus.__table__.columns._data.keys()
yang memberi Anda daftar yang bagus dan bersih:sumber
self.__table__.columns
akan "hanya" memberi Anda kolom yang ditentukan dalam kelas tertentu itu, yaitu tanpa kolom yang diwariskan. jika Anda membutuhkan semuanya, gunakanself.__mapper__.columns
. dalam contoh Anda, saya mungkin akan menggunakan sesuatu seperti ini:sumber
Dengan asumsi Anda menggunakan pemetaan deklaratif SQLAlchemy, Anda dapat menggunakan
__mapper__
atribut untuk mendapatkan mapper kelas. Untuk mendapatkan semua atribut yang dipetakan (termasuk hubungan):Jika Anda hanya menginginkan nama kolom, gunakan
obj.__mapper__.column_attrs.keys()
. Lihat dokumentasi untuk tampilan lain.https://docs.sqlalchemy.org/en/latest/orm/mapping_api.html#sqlalchemy.orm.mapper.Mapper.attrs
sumber
Untuk mendapatkan
as_dict
metode di semua kelas saya, saya menggunakanMixin
kelas yang menggunakan teknik yang dijelaskan oleh Semut Aasma .Dan kemudian gunakan seperti ini di kelas Anda
Dengan cara itu Anda dapat memanggil yang berikut pada sebuah instance
MyClass
.Semoga ini membantu.
Saya telah bermain-main dengan ini sedikit lebih jauh, saya sebenarnya perlu membuat instance saya
dict
sebagai bentuk objek HAL dengan tautannya ke objek terkait. Jadi saya telah menambahkan sihir kecil ini di sini, yang akan merayapi semua properti kelas yang sama seperti di atas, dengan perbedaan bahwa saya akan merayapi lebih dalam keRelaionship
properti dan membuatnyalinks
secara otomatis.Harap dicatat bahwa ini hanya akan berfungsi untuk hubungan yang memiliki kunci utama tunggal
sumber
from sqlalchemy.orm import class_mapper, ColumnProperty
di atas cuplikan kode Andamengembalikan sebuah dict di mana kunci adalah nama atribut dan nilai-nilai dari objek tersebut.
/! \ ada atribut tambahan: '_sa_instance_state' tetapi Anda dapat menanganinya :)
sumber
Saya tahu ini pertanyaan lama, tapi bagaimana dengan:
Kemudian, untuk mendapatkan nama kolom:
jobStatus.columns()
Itu akan kembali
['id', 'desc']
Kemudian Anda dapat mengulang, dan melakukan hal-hal dengan kolom dan nilai:
sumber