Дмитрий: Так, пока вдавался в теорию, пропустил практику =) Здесь, у вас во втором случае, пользователи файла будут подгружаться с lazy='dynamic', а файлы просто с lazy-load, это нужно учесть. Если количество пользователей у файла больше, чем количество файлов у пользователя, то во втором варианте все правильно. Если наоборот, то нужно переписать.
Дмитрий: Насколько я помню, по-умолчанию используется lazy-loading, и если нужно подгружать связанные данные по запросу, лучше все-таки указать dynamic, если речь об этом и если именно это вам нужно. Различие между lazy и dynamic, коротко, в том, что lazy загрузит коллекцию связанных объектов при первом доступе к полю, а dynamic вернет туда Query, что позволяет делать фильтрацию как с обычным запросом, устанавливать какие-то ограничения. lazy='dynamic' нужно тогда, когда у вас просто гигантское количество связанных записей, или когда очень важна скорость обработки, когда можно сразу отфильтровать нужное с критериями.
Если количество файлов у пользователя будет относительно небольшое, и, в большинстве случаев, вы не будете постоянно к ним обращаться при использовании User, можно использовать lazy по-умолчанию, то есть, как у вас во втором варианте. Здесь все зависит от специфики. К примеру, есть еще такая штука, как lazy='noload', которая вообще не будет никогда загружать связанные записи, для тех случаев, когда их просто нужно добавлять.
Дмитрий: указание backref как раз и предполагает, что будет двунаправленный доступ, backref дословно — «обратная ссылка». То, что вы текстом укажете в backref, будет полем класса, с которым будет связь, и по нему можно получить связанные обьекты. То есть, указали backref в Файлах как «uploaded_files», в рантайме можно будет написать user.uploaded_files (где юзер — экземпляр класса User), и он вернет связанные с этим юзером файлы в виде списка.
Это не прикол. Не вы ли задавали вопрос про дампер и __repr__? Если да, то там я подсказал решение для ограниченной выборки атрибутов mapped-инстанса, соответствующих колонкам таблицы, даже без ассоциаций. Атрибут, который здесь добавляется «на лету», таковым не является, потому и тот __repr__, что у вас выводится, не выведет этот атрибут (как и множество других, что есть в объекте).
Дебаг все таки лучше делать более явно, и отдельно от основного когда.
а items никак не меняется? Просто если следовать коду, то items все так же должен при print выводить текст SQL запроса. Вот если вместо print(items) написать for i in items: print i.UserItem.key, он выведет значение?
Для отладки я бы отдельно через logger.debug() выводил информацию, там и в логи (в т.ч. с временной и размерной ротацией) выводить можно, и в консоль. См. https://docs.python.org/2/library/logging.html и https://docs.python.org/2/howto/logging.html
Даже в базу через тот же SQLA =)
Причем, логи лучше вывести отдельно от кода:
import logging
log = logging.getLogger(...)
...
if app.Debug:
items = <...>.all()
log.debug(items)
Ну или как-то так =)
А надо именно чтобы печатал все данные через print? Все же тут предполагается, что над данными будет проводиться какая-то обработка в цикле, потому лучше без all(), т.к. таким образом вы не будете забивать память лишний раз, ну и время на это тратить тоже не будете. Для больших коллекций это имеет значение.
Как интересно, вообще ничего не печатает? None? И for i in items: print i тоже ничего? Это очень странно... Может, потому что питон третий? Да нет, не может такого быть =)
print(items) должен, вообще говоря, вывести текст запроса SQL.
Николай Павлов: Бесспорно, просто тут вопрос про энтерпрайз, потому и упомянул EE =)
А вообще, если абстрагироваться от вышенаписанного, то меня эти же самые стандарты и спецификации, в виде реализаций, повергли в восторг, особенно JPA. Java комьюнити задрало планку для всех до нереальной высоты. Потому, наверное, Java — выбор для enterprise =)
Ну вот Дейкстра что-то нашел =)
А вообще, проблема Java EE, на мой взгляд, в загроможденности спецификациями. Я не говорю, что спеки это плохо, наоборот, но там умудрились настолько все запутать, что более-менее распутали только к 7 версии. Плюс к этому, для на написания на Java EE7 веб-приложения, пришлось очень много собирать инфы по крупицам в сети, чтобы сделать то, что мне надо. Вроде и книжки есть, а по ряду задач все равно приходилось очень долго соображать, как тут и что. Ну, скажем, для message bundle я далеко не с первого раза нашел описание более-менее подробное. Особенно было туго с JPA =)
Я вот сейчас подумал... Тут, наверное, лучше написать класс-сателлит для данных из memcached, и как-то его связать с моделью, или даже сделать transient поле/метод у модели, и туда записывать нужную инфу. Ну или даже сделать так, чтобы инстанс модели сам получал нужное ему, а в контроллере просто метод вызвать в цикле. Тут много способов, я не знаю, что и как там у вас, но решить можно.
Ответ на этот вопрос сильно зависит от задачи, можно добавлять атрибуты, если будет гарантировано, что код, который этим пользуется, всегда будет его получать. Ну и потом чтобы в этом разобраться можно было: все таки бывает, что сам уже не помнишь, где и как решал задачу. А так вообще, я не пользовался memcached и решениями с кешированием, может, там это распространено =)
С .all() весьма странная история, должен как минимум _repr_ объекта вывести...
Понял свою ошибку, обновил ответ, поскольку это KeyedTuple, можно просто вызвать i.U.id
По второму вопросу, в принципе, никто не мешает вам просто сделать i.U.key = value в цикле, но мне как-то кажется, не очень это хорошо...