Контекстно-зависимая функция SQLAlchemy для создания составного значения при вставке и обновлении

Я пытаюсь разобраться, как добавить контекстно-зависимую функцию (например, def get_user_full_name()), которая будет запускаться из спецификаций по умолчанию и onupdate для столбца. Я пытаюсь установить составное поле, которое объединяет имя и фамилию в одно значение полного имени, чтобы избежать необходимости постоянно объединять два поля во всех запросах.

Я использую декларативный подход. Вот пример похожей модели:

class SomeMembers(Base):
    __tablename__ = 'some_members'
    __table_args__ = {'mysql_engine':'InnoDB'}

    SomeGroup = Column(Unicode(50), primary_key=True)
    UserID = Column(Unicode(50), primary_key=True)
    FullName = Column(Unicode(255), default=get_user_full_name, onupdate=get_user_full_name, index=True)
    FirstName = Column(Unicode(255), index=True)
    LastName = Column(Unicode(255), index=True)
    UserName = Column(Unicode(255))

Это функция, которую я написал, которая сообщает в трассировке стека, что ни ключи FirstName, ни LastName недействительны:

def get_user_full_name(context):
    return " ".join((context.compiled_parameters[0]['FirstName'],context.compiled_parameters[0]['LastName']))

Мне не ясно, как я могу сослаться на существующие данные двух столбцов (Имя и Фамилия), чтобы создать составное значение для хранения для удобного поиска. Например, если бы у меня был пользователь по имени Джон Доу, метод get_user_full_name должен принимать «Джон» и «Доу» и возвращать значение полного имени «Джон Доу».

В документации это относится к context.current_parameters, но которого нет в моем случае. Я подозреваю, что это потому, что мы используем декларативный подход. Если бы это сработало, моя функция get_user_full_name выглядела бы так:

def get_user_full_name(context):
    return " ".join((context.current_parameters['FirstName'],context.current_parameters['LastName']))

Я знаю, что это, вероятно, тривиально, но я не могу взломать код, где хранится эта информация и как получить к ней динамический доступ.

Небольшое понимание будет высоко оценено. Я также открыт для более элегантного подхода.

Заранее спасибо...

Ваше здоровье,

Павел


person PlaidFan    schedule 06.09.2010    source источник


Ответы (2)


На всякий случай, если кто-то ищет ответ.

Вы можете использовать mapper-events

@event.listens_for(SomeMembers, 'before_insert')
def before_insert_function(mapper, connection, target):
        target.FullName = f"{target.FirstName} {target.LastName}"
person julste    schedule 20.11.2019

Я попробовал следующее выражение:

from sqlalchemy.sql.expression import column, literal, literal_column

Column('full_name', String, onupdate=literal_column("first_name") + literal(" ") + literal_column("last_name"))

Вроде работает, но обновляет full_name предыдущими значениями first_name и last_name. Использование column дает тот же результат.

Будет ли работать столбец composite? ?

person muhuk    schedule 02.03.2011