Веб-программинг

Интересное и полезное про Php, фреймворк Yii1 и Yii2.
Использую Php, JS, Jquery, Angular, Bootstrap, MySQL, Docker, Git, Trello, Nginx и Apache.
Интегрирую API Яндекса, Google, PayPal, Fb, Vk, GeoNames, Robokassa.

21 июля   apache2   nginx   php   php5.6   php7.1

Конвертируем поле json в jsonb в PostgreSQL

На чистом SQL это можно сделать так:

ALTER TABLE table_name ALTER COLUMN column_with_json SET DATA TYPE jsonb USING column_with_json::jsonb

Если делать миграцию на Yii2, то можно сделать так:

public function safeUp()
{
    $this->execute('ALTER TABLE table_name ALTER COLUMN column_with_json SET DATA TYPE jsonb USING column_with_json::jsonb');
}
3 июля   alter column   alter table   json   jsonb   migrate   php   PostgreSQL   sql

Назначим права доступа на директории и файлы на Linux

Все знают, что выставить, например, права 755 на все вложенные файлы можно так:

chmod -R 755 /path/to/dir

А вот, чтобы выставить права только на вложенные директории, может пригодиться команда:

find /path/to/dir -type d -exec chmod 755 {} +

Только на влженные файлы:

find /path/to/dir -type f -exec chmod 644 {} +
30 июня   chmod   linux

PostgreSQL: группируем данные и оборачиваем в массив

Вдруг стоит задача получить сгруппированный список, например из связанной таблицы, да при том оформить построчно данные в виде массива, как-то так:

id author book_ids
1 1 [1, 4]
2 2 3
3 3 [2, 5, 7]

Ну давайте посмотрим, что можно с тим сделать в PostgreSQL.

Вот представим есть 3 таблицы:

  • Книги, `books`
  • Авторы, `authors`
  • Связанная таблица Книга — Автор, `book_author`.

Опишем данные:

Табл `books`:

serial id
string name, Название книги
timestamp create_date, Дата выпуска

id name create_date
1 Преступление и наказание ...
2 Анна Каренина ...
3 Мёртвые души ...
4 Братья Карамазовы ...

Табл `authors`:

serial id
string name, Имя автора
string lastname, Фамилия
string middlename, Отчество (необязательное)
datetime birth_date, День рождения автора

id name lastname middlename birth_date
1 Федор Достоевский Михайлович ...
2 Николай Гоголь ...
3 Лев Толстой Николаевич ...

Соответственно, у книги может быть несколько авторов, и автор может написать несколько книг, потому и нужна связанная таблица:

Табл `book_author`:

serial id
int book_id
int author_id

id book_id author_id
1 1 1
2 2 3
3 3 2
4 4 1

Задача: получить сгруппированный список Авторов и написанных ими книг в виде массива, т.е:

id author book_ids
1 1 [1, 4]
2 2 3
3 3 2

SQL выражение может быть таким:

SELECT array_to_json(array_agg(concat(book_id))) as book_ids, author_id
FROM "book_author"
GROUP BY author_id;

Если же составлять такой запрос в Yii2, то выглядить это может вот так:

$query = BookAuthor::find()
    ->select([
        new Expression("array_to_json(array_agg(concat(".BookAuthor::tableName().".book_id))) as book_ids"),
        BookAuthor::tableName().'.author_id',
    ])
    ->joinWith('author')
    ->groupBy([BookAuthor::tableName().'.author_id'])
    ->indexBy('author_id');

Либо можно передать в провайдер:

$dataProvider = new ActiveDataProvider([
    'query' => $query->all(),
]);

Стоит обратить внимание, что я добавил жадной загрузки в виде joinWith('author'). Эти связанные данные лучше одним запросом достать, если планируется делать вывод во представлении всего списка.

PostgreSQL: преобразование типа поля VARCHAR в INTEGER

Стандартными средствами sql это можно сделать так:

ALTER TABLE table_name ALTER COLUMN column_name TYPE integer USING (column_name::integer);

А миграцией в Yii2 можно сделать так:

public function safeUp()
{
    $this->execute('alter table {{%table_name}} alter column column_name TYPE integer USING (column_name::integer);');
}

В итоге мы получим преобразованное поле Integer

27 июня   alter table   PostgreSQL   sql   yii2
Ctrl + ↓ Ранее