Is there any way in SQLAlchemy by reflection or any other means to get the name that a column has in the corresponding model? For example i have the person table with a column group_id. In my Person class this attribute is refered to as 'group' is there a way to dynamically and generically getting this without importing or call the Person class?
3 Answers
Given a SQLAlchemy Core column and a SQLAlchemy ORM mapped table, you can obtain the name of the mapped attribute in the table by using the Mapper.get_property_by_column method:
import sqlalchemy as sa
from sqlalchemy import orm
Base = orm.declarative_base()
class Student(Base):
__tablename__ = "student"
id = sa.Column("id", sa.Integer, primary_key=True)
group = sa.Column("group_id", sa.Integer)
# We have a column (group_id) and want to see what attribute (group) it's mapped to
mystery_column = Student.__table__.c.group_id
mapper = sa.inspect(Student)
mapped_property = mapper.get_property_by_column(mystery_column)
assert mapped_property.key == "group"
You can see this being used inside sqlalchemy-mixins
Comments
We can use inspect method of sqlAlchemy, which would return mapper object when passed for sqlAlchemy model.
DB column is returned when mapper object is accessed with respective attribute name of model using mapper.c[attribute_name]; So db column name can be fetched via mapper.c[attribute_name].name;
For fetching attribute name we can traverse over attribute names of model which can be obtained using mapper.attrs.keys() and then compare db column name with respect to associated attribute name as done in below code snippet.
from sqlalchemy import inspect
mapper = inspect(model_class)
attr = mapper.attrs
keys = attr.keys()
db_column_name = 'db_column_name'
attribute_name = next((attr_name for attr_name in keys if mapper.c[attr_name].name == db_column_name), None)
print(attribute_name)
3 Comments
inspect and model_name?
Personclass is where the mapping between the attribute name (group) and column name (group_id) is defined. That information doesn't exist anywhere else.