Страницы

Поиск по вопросам

среда, 21 ноября 2018 г.

выборка из 3 таблиц с объединением данных

Добрый вечер, имеется проблема, которую никак не могу решить. Существует 3 таблицы:
tm_posts - данные о постах и страницах tm_attributes - данные о тегах и категориях tm_relationships - связи 1 и 2 таблицы
Пример структуры:
tm_posts:
id | name | text ------------------- 1 | kols | <ТЕКСТ> 2 | ando | <ТЕКСТ> 3 | krot | <ТЕКСТ>
tm_attributes:
id | sign | attr_name ------------------- 1 | tag | учебник 2 | tag | дождь 3 | cat | личное 4 | cat | опыт
tm_relationships:
id | id_attr | id_post ------------------- 1 | 1 | 2 2 | 2 | 2 3 | 3 | 2 4 | 4 | 2
Мне нужно получить такой результат по нику ando:
id | name | text | tags | category | ----------------------------------------------------- 2 | ando | <ТЕКСТ> | учебник,дождь | личное,опыт |
Т.е. берутся данные из таблицы tm_posts по нику ando, ищется связка тегов и категорий по id поста в таблице tm_relationships. После чего получаем данные из таблицы tm_attributes. Эти данные сливаем в строку.
Вот что получилось сделать:
SELECT t1.*, GROUP_CONCAT(t3.attr_name) As `tags` FROM tm_posts t1 JOIN tm_relationships t2 ON t1.id = t2.id_post JOIN tm_attributes t3 ON t3.id = t2.id_attr WHERE t1.name= 'ando' AND t3.sign = 'tag' GROUP BY t1.id
Этот код выводит все, кроме категорий. Как мне сюда добавить еще и категории.
-----------------------------Добавлено:
Необходимо выбрать все записи из БД с категорией "личное", но при этом к каждой записи нужно приклеить колонку со связкой тегов.
Структура таблиц остается такая же. Результат должен выдать, примерно такой:
id | name | text | tags | category | ---------------------------------------------------------------------- 2 | ando | <ТЕКСТ> | учебник,дождь | личное | 5 | ник | <ТЕКСТ> | какие-то теги | личное | 6 | ник | <ТЕКСТ> | какие-то теги | личное |
Т.е. выбрались все записи с тегами, но только с определенной категорией "личное"


Ответ

Думаю можно сделать два join к tm_attributes наподобие
SELECT t1.*, GROUP_CONCAT(t3.attr_name) As `tags`,GROUP_CONCAT(t4.attr_name) As `cats` FROM tm_posts t1 JOIN tm_relationships t2 ON t1.id = t2.id_post left JOIN tm_attributes t3 ON t3.id = t2.id_attr and t3.sign = 'tag' left JOIN tm_attributes t4 ON t4.id = t2.id_attr and t4.sign = 'cat' WHERE t1.name= 'ando'
GROUP BY t1.id
Для выбора только категории личное пришел в голову только такой запрос fiddle
1) сначала выбираем все Post с категория личное
2) делаем join к категориям
select cat_data.*, GROUP_CONCAT(t3.attr_name) As `tags` from (select t1.*,t4.attr_name from tm_attributes t4 join tm_relationships t2 on id_attr=t4.id join tm_posts t1 on id_post=t1.id where t4.sign = 'cat' and t4.attr_name='личное' ) cat_data join tm_relationships t2 on id_post=cat_data.id left JOIN tm_attributes t3 ON t3.id = t2.id_attr and t3.sign = 'tag' group by cat_data.id

Что правильно тестировать в юнит-тестах?

Предположим есть несколько классов A, B и C. Мы тестируем A. Остальные классы - моки. У класса A есть метод, внутри которого он использует B и C, и выдает результат.
Нужно-ли тестировать то, что класс A взаимодействует с B и C, или написать один тест, в котором будет проверяться результат выполнения метода A?
Делать ли такой тест в следующем случае:
class A implements B.OnBarCallback { private B b;
public A(B b) { this.b = b; }
public void foo() { b.bar(this); }
@Override public void onBar() { // do something } }
// тест вызова B void testCallB() { B mockB = mock(B.class); A a = new A(mockB); a.foo(); verify(mockB).bar(any(OnBarCallback.class)); }
// тест callback void testACallback() { B mockB = mock(B.class); A a = new A(mockB); a.onBar(); // do verify something }
Правильно ли вручную дергать метод колбэка в тесте?


Ответ

Если пойти совсем по правилам, то юнит тест должен тестить минимальную единицу кода. У меня есть такое внутреннее правило - если мне вдруг понадобилось продебажить выполнение юнит теста, так как я не понимаю, как оно работает - значит, это не юнит тест, он тестирует слишком большой кусок кода.
Поэтому, если классы В и С достаточно большие и не тривиальные (к примеру, они читают файлы с диска, скачивают с интернета), то лучше их замокать и в классе A тестить с моками. А если методы B/C складывают два числа, то я не вижу особой причины их мокать.
Нужно-ли тестировать то, что класс A взаимодействует с B и C
Но никто не отменяет тестов взаимодействия классов вместе. Просто это называется уже интеграционные тесты. И они также нужны и полезны.
или написать один тест, в котором будет проверяться результат выполнения метода A?
А вот сколько тестов написать - это уже философский вопрос. Но одного обычно мало бывает.

Объединение подколлекций в одну коллекцию с помощью Linq

“Один пользователь - одна база данных” - правильно ли, и если нет, то почему?

Работаю над проектом связанным с аграрным производством. Заказчик очень пристрастен к вопросам безопасности. Одним из пунктов технического задания есть использование для каждого пользователя отдельной базы данных. Аргументация данного подхода состоит в безопасности системы и если злоумышленники взломают одну базу, к остальным добраться не смогут. Когда я ответил, что с таким подходом к построению структуры базы данных сталкиваюсь впервые и, что возможно, такой подход не практикуется. Однако заказчик ответил, что он уже создавал продукт, который использует данный принцип, один пользователь - одна база данных.
Поэтому есть два вопроса:
Насколько данный подход правильный / неправильный и как его возможно реализовать. Если данный подход неправильный, как аргументировать это заказчику?
При этом нужно учитывать что у приложения клиент-серверная архитектура.


Ответ

Подход вполне возможный и в некоторых случаях - логичный. Называется такая архитектура мультитенантной, используется в облачных технологиях чаще всего.
Явные плюсы:
Sql доступ конкретного клиента можно (я бы даже сказал нужно) дополнительно ограничивать sql учеткой. Независимость клиентов друг от друга. Независимость данных клиентов друг от друга.
Что не совсем ясно по вашему вопросу и надо будет учитывать:
Есть ли общая точка входа для сервисных операций? Она должна быть либо защищена от клиентов, либо клиенты от неё. Какая архитектура приложения - клиент-БД или клиент-сервер-БД? В первом случае отдельная база на клиента выглядит обязательной, во втором - в зависимости от нагрузки и требований клиентов. Есть ли (нужна ли) у клиентов возможность обновления на разные версии программы? Одна база на всех не даст вам такую возможность.
Можно найти ещё причин, надо смотреть по ситуации.

Подскажите как сверстать эту секцию

Используя flexbox я смогу их так установить, но что делать с линиями? Или же сделать что-то на подобии адаптивной галереи, а как тогда адаптивить, что с линиями делать?
Как верстать такую секцию? Подскажите. Может быть примеры есть какие.


Ответ

Как вариант
* { padding: 0; margin: 0; box-sizing: border-box; } .b { max-width: 960px; margin: 15px auto; display: flex; justify-content: space-between; counter-reset: b-item; } .b-item { max-width: 220px; margin: 0 auto; padding: 25px; position: relative; text-align: center; display: flex; flex-direction: column; } .b-item:nth-of-type(even) { padding-top: 50px; } .b-item:nth-of-type(even) p { order: 1; } .b-item:before, .b-item:after { border: 1px solid #ccc; width: 24px; height: 24px; line-height: 24px; text-align: center; border-radius: 50%; display: block; margin: 10px auto; position: relative; z-index: 99; background: #fff; } .b-item:nth-of-type(odd):after, .b-item:nth-of-type(even):before { counter-increment: b-item; content: counter(b-item)" "; } .b-item .fa { font-size: 26px; color: #c00; } .b-item .fa:after { content: ''; border-bottom: 1px dashed #555; width: 100%; height: 1px; position: absolute; top: 50%; left: 0; } .b-item .fa:nth-of-type(1):after { left: 50%; } .b-item:nth-of-type(odd) .fa:after { transform: rotate(-16deg); } .b-item:nth-of-type(even) .fa:after { transform: rotate(16deg); } .b-item:last-of-type .fa:after { border: none; } @media screen and (max-width: 767px) { .b { flex-wrap: wrap; } .b-item:nth-of-type(even) { padding-top: 25px; } .b-item .fa:after { display: none; } .b-item:nth-of-type(odd):after { display: none; } .b-item:before { counter-increment: b-item; content: counter(b-item)" "; } }

text text text text text text

text text text text text text

text text text text text text

text text text text text text

text text text text text text

text text text text text text


Android анимация вращения

Есть RelativeLayout с несколькими view внутри. Как сделать анимацию вращения вокруг оси Y как на рисунке?


Ответ

Используйте класс ObjectAnimator. Очень прост в использовании
ObjectAnimator animation = ObjectAnimator.ofFloat(yourView, "rotationY", 0.0f, 360f); animation.setDuration(2400); animation.setRepeatCount(ObjectAnimator.INFINITE); animation.setInterpolator(new AccelerateDecelerateInterpolator()); animation.start();

Мусорные картинки при обновлении имеющейся

Думаю это большая проблема в Django, но панацеи (как я понимаю) нет.
У меня есть модель пользователя с полем ImageField для аватарки. Из личного кабинета пользователь меняет аватарку передавая через форму новую картинку. Все хорошо, аватарка изменена и храниться у меня в папке, но старая аватарка(фаил) так же остался в папке!
Есть ли универсальный способ чистить "устаревшие" картинки? Возможно требуется переопределение метода save() когда я сохраняю форму в view? Я не совсем понимаю как это все сделать...


Ответ

Да, такая особенность у django действительно имеется - старые картинки не удаляются.
Проблему можно решить несколькими методами
Переопределить метод save. Суть заключается в том, что нужно получить объект, хранящийся на сервере, проверить различаются ли между ними изображения и удалить старое:
def save(self, *args, **kwargs): try: this = MyModelName.objects.get(id=self.id) if this.MyImageFieldName != self.MyImageFieldName: this.MyImageFieldName.delete() except: pass super(MyModelName, self).save(*args, **kwargs) Отслеживать сигналы pre_save и post_save соответственно манипулируя удалением из них (сложно) Время от времени проходиться периодической задачей по файлам в папке и всем полям FileField, выискивая и удаляя лишние
Но как по мне лучше всего с этой задачей справляется дополнение django cleanup. Поэтому советую установить его и забыть про эту проблему