57

I just want to programatically determine the name of an SQLalchemy model's primary key.

Marcin
  • 48,559
  • 18
  • 128
  • 201
Peter
  • 12,274
  • 9
  • 71
  • 86
  • 6
    If this solution works for you, it's completely acceptable to add your solution as an answer and mark it as "answered". This helps for when people are looking for unanswered questions. – Mark Hildreth Jul 20 '11 at 07:48

3 Answers3

67

If using SQLAlchemy version 0.8 or later, you should use the runtime inspection API.

If the model class is User and the sole primary key is id,

>>> from sqlalchemy.inspection import inspect
>>> inspect(User).primary_key[0].name
'id'

If the model class is User and there are many primary keys,

>>> from sqlalchemy.inspection import inspect
>>> [key.name for key in inspect(User).primary_key]
['id', 'name']

If using SQLAlchemy version less than 0.8, you should use the class_mapper() function instead.

>>> from sqlalchemy.orm import class_mapper
>>> class_mapper(User).primary_key[0].name
'id'

In this case, the inspect() function and the class_mapper() function return the same object, but using inspect() is more future-proof.

argentpepper
  • 4,202
  • 3
  • 33
  • 45
  • 1
    I know this is really old answer but it should be noted, all of the above return the column names which are not necessarily going to match the class property names. Mapper also has a method `get_property_by_column` which can be used to access the `ColumnProperty` object corresponding to the column in the primary key. `ColumnProperty` in turn gives you access to `key`, the name of the property, `class_attribute` to access the class `InstrumentedAttribute`, etc. – George Barbăroşie Jul 30 '21 at 13:01
9

If class is "User", and there is just 1 primary key, do this*:

User.__mapper__.primary_key._list[0].name

*Moved from the question.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
  • Or if you need all the primary keys you can do the list comprehension stated above: `[k.name for k in User.__mapper__.primary_key]` – elliotwesoff Dec 12 '18 at 10:01
2

Assuming the declarative model class is User,

>>> list(User.__table__.primary_key)[0].name
'id'

Or for Membership which has a composite primary key

>>> [pk.name for pk in Membership.__table__.primary_key]
['user_id', 'group_id']
Frozen Flame
  • 3,135
  • 2
  • 23
  • 35