Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Базы данных
  • » Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных? [RSS Feed]

#1 Март 18, 2015 15:14:26

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

Добрый день. Использую Flask + SQLAlchemy.
Имеется модель такого типа:

class Entry(db.Model):
    __tablename__ = 'entries'
    name = db.Column(db.String(100))
    created = db.Column(db.DateTime(), default=datetime.now)
    updated = db.Column(db.DateTime(), default=datetime.now, onupdate=datetime.now)

Как подменить время создания и обновления? К примеру для такого теста:
class ViewTestCase(AppliactionTestCase):
    def test(self):
        with freeze_time("2014-06-01 16:00:00"):
            db.session.add(Entry(name="title"))
            db.session.commit()
        entry = db.session.query(Entry).first()
        self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))
        self.assertEqual(entry.updated, datetime(2014, 6, 1, 16, 0, 0))
        with freeze_time("2014-07-01 17:00:00"):
            entry.name = 'edited title'
            db.session.add(entry)
            db.session.commit()
       entry = db.session.query(Entry).first()
       self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))
       self.assertEqual(entry.updated, datetime(2014, 7, 1, 17, 0, 0))

Для подмены времения я использую freezegun. Но с ходу он не подменяет.
Я также пытался с помощью mock патчить db.DateTime.python_type, что бы он возвращал FakeDatetime, но результат тот же.

Я обратил внимание что если определять поля так:
created = db.Column(db.DateTime(), default=lambda: datetime.now())
То все работает. Но переписывать все под тесты не охота, да и неправильно это.

Подскажите, если кто сталкивался с этим, или знает где нужно подменить метод, отзовитесь, пожалуйста.

Отредактировано qnica (Март 18, 2015 16:28:11)

Офлайн

#2 Март 18, 2015 16:02:30

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

Что Вы тестируете? Я, если честно, понять не могу

Офлайн

#3 Март 18, 2015 16:39:30

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

У меня была опечатка в последнем ассерте.
Вообще это выдернута часть теста. В тесте между сохранениями дергается рест апи.
Суть этого фрагмента: сохранять в заданное время сущность и проверить что ее время обновления, то, в которое мы его сахранили.

Офлайн

#4 Март 18, 2015 16:50:00

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

Сложновато Вы придумали. Я бы в тесте сохранил время создания и после обновления проверил бы, что времена не совпадают. Или нужна повышенная точность? Просто подмена для такого теста уж как-то слишком витиевато

Офлайн

#5 Март 18, 2015 17:18:03

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

Это приемочный тест. Хотелось бы в нем все механизмы отфиксировать.
Мне просто не понятно где именно нужен патч для datetime. Ведь если я подсовываю в самой модели лямюду в default то все работает нормально:

created = db.Column(db.DateTime(), default=lambda: datetime.now())

P.S. Еще вопрос немного не по теме. А как принудительно обновить запись если поля не менялись(что бы сработали только функции на onupdate)?
Я недавно начал использовать Flask+SQLAlchemy, до этого все проекты были на Django. И иногда возникает мысль: “Ага, на джанго я это делал так, а как мне это же сделать c алхимеей”. Хотя может это не совсем верный подход

Отредактировано qnica (Март 18, 2015 17:18:32)

Офлайн

#6 Март 18, 2015 17:53:39

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

пропробуй явно время задать зачем freezegun
и зачем обновлять запись если поля не изменились?

Офлайн

#7 Март 18, 2015 18:02:18

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

По условию у каждой записи должн быть свой период актуализации. Когда запись “протухает” об этом оповещается клиент, который сверяет данные и если все нормально, то сохраняет запись, тем самым актуализируя ее.
В приемочном тесте я действую от роли пользователся, дергая рест апи. По этому я использую freezegun и стараюсь не вмешиваться в процессы создания записей руками.

Офлайн

#8 Март 18, 2015 18:06:24

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

qnica
Мало того, что он неверный, он еще губителен.

По второму вопросу. Попробуйте метод .update(). Но Вы опять колдуете Неужели в объекте нет ни одного поля, которое можно было бы обновить и проверить. Запись хранит только время? Тогда спроектированная БД, как бы не было печально, неверна в принципе…

Офлайн

#9 Март 18, 2015 19:37:02

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

qnica
не совсем понимаю что вы делаете
как происходит актуализация? изменение поля update?
что имеется в виду под оповещением клиента?

Офлайн

#10 Март 20, 2015 15:24:19

qnica
Зарегистрирован: 2014-01-16
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?

4kpt_III
Но Вы опять колдуете Неужели в объекте нет ни одного поля, которое можно было бы обновить и проверить. Запись хранит только время?
sander
как происходит актуализация? изменение поля update?

Наверное я не правильно выразился. По мимо времени есть другие поля, но содержимое их не менялось. Т.е. нужно принудительно их перезаписать.

Офлайн

  • Начало
  • » Базы данных
  • » Как при помощи mock и SQLAlchemy изменить дату при автосохранении объекта в базу данных?[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version