Get python defaults from sqlalchemy column metadata

105 Views Asked by At

I need to get python-executed expressions from sqlalchemy column metadata for all columns in all tables of my app. I can get defaults (or server defaults) as sqlalchemy objects. They are:

  • ScalarElementColumnDefault (e.g. default string for string column)
  • CallableColumnDefault (e.g. uuid4 for id column)
  • DefaultClause (e.g. datetime.now for created_at column)
  • SqlAlchemy expressions (e.g. sa.text) As I know, there maybe some user typed objects.

I know how to get value from scalar element column default (property "arg"), but for the others I can't find anything useful in object's attributes. I need to get the proper function able to calling (e.g. to get UUID from uuid4 function). How can I get it?

This is how I get defaults as sqlalchemy objects:

defaults = {}
for attr_name, attr in MyModel.__dict__.items():
    if (hasattr(attr, "default") or hasattr(attr, "server_default")) and (
        attr.default is not None or attr.server_default is not None
    ):
        defaults[attr_name] = attr.default or attr.server_default

I do this on the initialization of the app. After that when I try to create object in db, I want to do smth like

if "my_column_with_default" not in in_obj:  # in_obj is a dict with input data, dumped from pydantic model
    in_obj["my_column_with_default"] = defaults["my_column_with_default"]()

You'd say that sqlalchemy does this anyway without my participation, but I want to do some validation before transaction in database

UPD: DefaultClause is always the result of server_default value (callable or scalar - doesn't matter), meanwhile CallableColumnDefault appears when you pass callable as default value of the column

0

There are 0 best solutions below