LINUX.ORG.RU

Вопрос по фреймворкам. Где такое есть и как?


0

1

Вчера решил один проектик сделать на Play! framework для набивания руки.

И почти сразу наткнулся на такую фишку. Там отсутствует штатно вариант размещения записи в параметрах AcriveRecords-объекта на внешний объект не только по ID, но и по ClassName+ID.

Ну, грубо говоря, например, есть объект «Ключевое слово (Тэг)». К нему могут быть привязаны объекты разных классов. Скажем, «Новость», «Фотоальбом», «Событие» и т.п.

Соответственно, есть таблица tag_links типа many-to-many вида (tag_id, target_class_name, target_object_id). Или даже target_class_id вместо target_class_name, где class_id — автоматически генерируемый уникальный целочисленный ID класса для экономии места на больших списках связей и для ускорения выборки.

А у класса TagLink есть свойство target, возвращающее объект, на который ссылается выбранная связь. Ну и до кучи методы возвращения списков объектов по условиям, предзагрузка объектов по одному-нескольким SQL-запросам, чтобы не дёргать по запросу на каждый новый target и т.п.

~~~

В каких популярных фреймворках (в первую очередь интересует JVM, на втором месте — Python) такое реализовано «из коробки» и как (несложный пример приветствуется)?

★★★★★

Это что-то вроде contenttypes framework из Django?

В джанге это табличка (id, name, app_label, model) и сахарок вроде ContentType.get_object_for_this_type(username='Guido')

KDE41user ()
Ответ на: комментарий от KDE41user

В джанге это табличка (id, name, app_label, model)

Что это за поля? По идее, там должны быть, как минимум, три поля. В нашем примере это:
tag_id — id основного объекта, ссылающегося на переменные
target_class_name или target_class_id — имя или id класса целевых объектов разного типа
target_object_id — id целевых объектов.

Эти три поля должны составлять unique_id.

В общем случае возможны варианты единой ссылочной структуры, когда вместо tag_id у нас тоже пара (source_class_name/id, source_object_id), чтобы можно было одной таблицей связывать любые виды объектов.

KRoN73 ★★★★★ ()

Для иллюстрации, в моём случае речь идёт о неком «Тематическом рубрикаторе» в рамках всего проекта. Т.е. есть объект «Тема», с которым могут быть связаны любые другие объекты любых типов.

Нужно уметь быстро оперировать связями. Например:
— Вытаскивать Темы с наибольшим числом изменившихся объектов за сутки
— Вытаскивать Темы с наибольшим числом объектов за всю историю, со счётчиком объектов
— Вытаскивать списки объектов заданного типа для указанной темы
— Вытаскивать списки тем для заданного объекта или группы объектов и вытаскивать по (другим) условиям списки объектов, связанных с этими темами

KRoN73 ★★★★★ ()

Вообще не понял, что ты хочещь. Но смотреть надо в любом случае в сторону ORM.

VirRaa ★★★ ()
Ответ на: комментарий от VirRaa

ORM тут в общем случае ортогонален, но подразумевается уже по наличию упоминания ActiveRecords.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

В случае с ORM нет никакой нужды хранить class_id, так как объект сам из себя представляет сущность и обработчик этой модели.

VirRaa ★★★ ()

Не совсем понял, поэтому могуть быть не в тему со своим банальным предложением, но все же предложу сделать базовый класс, к которому будут привязаны тэги, а от него уже наследовать «Новость», «Фотоальбом», «Событие».

winlook38 ★★ ()
Ответ на: комментарий от KRoN73

Эти три поля должны составлять unique_id.

Нет, в джанге «из коробки» есть только имя приложения (модуля) и название класса. Для «единой ссылочной структуры» нужно будет создать свою таблицу (contenttype_id, object_id).

Из документации:

Together, get_object_for_this_type() and model_class() enable two extremely important use cases:

Using these methods, you can write high-level generic code that performs queries on any installed model — instead of importing and using a single specific model class, you can pass an app_label and model into a ContentType lookup at runtime, and then work with the model class or retrieve objects from it.

You can relate another model to ContentType as a way of tying instances of it to particular model classes, and use these methods to get access to those model classes.

Таким способом в джанге реализованы ACL в админке, теги, логгирование действий и пр.

KDE41user ()
Ответ на: комментарий от VirRaa

В случае с ORM нет никакой нужды хранить class_id

Как без идентификатора класса ссылка на объект будет храниться в БД?

KRoN73 ★★★★★ ()
Ответ на: комментарий от winlook38

но все же предложу сделать базовый класс

id целевых объектов могут пересекаться

Предлагаешь делать лишнюю таблицу мапинга id привязок на конкретные объекты? Тогда мы возвращаемся к исходной задаче :)

KRoN73 ★★★★★ ()
Ответ на: комментарий от KDE41user

Что-то похоже на массу ручной работы. Но примерно, вроде, представил.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

У меня в незаконченном проекте есть базовый класс (id, timestamp, автор, тэги), к которому уже привязываются различные свойства (текст, заголовок, картинка). Набор свойств определяет тип объекта (запись в блоге, картинка в галерее, новость). Таким образом у меня id сохраняет уникальность. Я пишу тестовый проект чисто для себя, чтобы проверить работоспособность идеи, но уже сейчас подозреваю, что узким местом станет нагрузка на БД, так что предлагать такое на реальный прект даже боюсь.

winlook38 ★★ ()

К нему могут быть привязаны объекты разных классов. Скажем, «Новость», «Фотоальбом», «Событие» и т.п.

Через наследование от общего родителя, не?

belous_k_a ()
Ответ на: комментарий от belous_k_a

Через наследование от общего родителя, не?

Я выше обращал внимание, что это (в плане хранения) разные таблицы совершенно разной структуры и с разными, в т.ч. совпадающими, id.

KRoN73 ★★★★★ ()
Ответ на: комментарий от pi11

Спасибо, погляжу позже внимательно. Беглым взглядом ничего не понял, слишком наворочали, ИМХО :)

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

в т.ч. совпадающими, id.

Это в принципе единственное ограничение

belous_k_a ()
Ответ на: комментарий от KRoN73

Это унылое говно. Никогда так не делай. Потом при серьезных запросах нужно будет городить из ContentType и itertools костыли, чтобы сделать один запрос из нескольких таблиц, а потом еще и сортировать руками.

xpahos ★★★★★ ()

Play! framework
AcriveRecords-объекта

щито? Помойму там есть только Hibernate JPA. Вот его и гуглить.

или таки приделали настоящую Active Record?

stevejobs ★★★★☆ ()

Погуглил по кейворду «Hibernate JPA composite primary keys»

Уже первая ссылка ведет на что-то осмысленное, но разбираться было лень.

stevejobs ★★★★☆ ()
Ответ на: комментарий от stevejobs

composite primary keys

Это, нифига, не составной первичный ключ. Это комбинация уникального идентификатора типа объекта (модель/имя класса/id класса) и id объекта. Используется только в таблицах/моделях другого, ссылающегося объекта.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

эээ, может, тогда так?

@Entity
@Table(name = "TAG"
       uniqueConstraints={@UniqueConstraint(columnNames={"tag_id","target_class_id","target_object_id")})
public class Tag{
    @Id(name = "tag_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int tagId;

    @Column(name = "target_class_id", nullable = false)
    private int targetClassId;

    @Column(name = "target_object_id", nullable = false)
    private int targetObjectId;
}
stevejobs ★★★★☆ ()

смотрю, с питоном тут какие-то проблемы )
если что - в рельсах это называется Polymorphic Associations

kelyar ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.