Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Таблица, из которой было взято поле. / 7 сообщений из 7, страница 1 из 1
02.09.2015, 19:26
    #39041869
Warstone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Таблица, из которой было взято поле.
Задумался очередной раз об ОРМе. Пока все в виде ресерча.

Есть исходные данные:
Код: sql
1.
2.
CREATE TEMP TABLE temp1 AS ( SELECT t::BIGINT AS id, ('data ' || t)::TEXT AS data FROM generate_series(1, 100) t);
CREATE TEMP TABLE temp2 AS ( SELECT t::BIGINT AS id, ('data ' || t)::TEXT AS data FROM generate_series(1, 100) t);

Есть запрос:
Код: sql
1.
SELECT t1.id, t2.data FROM temp1 t1 LEFT JOIN temp2 AS t2 ON t1.id = t2.id;

Хотелось-бы программно знать к какой таблице принадлежат id и data (типы их нам должен вернуть клиент Пг). Вообще можно узнать вот так:
Код: sql
1.
EXPLAIN VERBOSE SELECT t1.id, t2.data FROM temp1 t1 LEFT JOIN temp2 AS t2 ON t1.id = t2.id;

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
                                     QUERY PLAN
------------------------------------------------------------------------------------
 Merge Left Join  (cost=161.29..268.01 rows=6728 width=40)
   Output: t1.id, t2.data
   Merge Cond: (t1.id = t2.id)
   ->  Sort  (cost=80.64..83.54 rows=1160 width=8)
         Output: t1.id
         Sort Key: t1.id
         ->  Seq Scan on pg_temp_19.temp1 t1  (cost=0.00..21.60 rows=1160 width=8)
               Output: t1.id
   ->  Sort  (cost=80.64..83.54 rows=1160 width=40)
         Output: t2.data, t2.id
         Sort Key: t2.id
         ->  Seq Scan on pg_temp_19.temp2 t2  (cost=0.00..21.60 rows=1160 width=40)
               Output: t2.data, t2.id
(13 rows)
Но каждый раз запускать EXPLAIN VERBOSE - не вкусно. Пните куда почитать - вдруг есть специальный режим или еще чего-нибудь в этом роде?..

Надо для того, чтобы можно было понять как представлять, допустим, текст или JSON или BYTEA в приложении, если есть своя схема БД.
...
Рейтинг: 0 / 0
03.09.2015, 06:13
    #39041998
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Таблица, из которой было взято поле.
Warstone,

Мне кажется вы не с той стороны к задаче подходите.
Когда база дает ответ там есть информация о всех типах колонок.
Через libpq она доступна через вызов:
PQftype
Returns the data type associated with the given column number. The integer returned is the internal OID number of the type. Column numbers start at 0.

Oid PQftype(const PGresult *res,
int column_number);
You can query the system table pg_type to obtain the names and properties of the various data types. The OIDs of the built-in data types are defined in the file src/include/catalog/pg_type.h in the source tree.

(из http://www.postgresql.org/docs/9.4/interactive/libpq-exec.html#LIBPQ-EXEC-SELECT-INFO )

Многие известные мне API к другим языкам так или иначе построены поверх LibPQ и дают доступ к этой информации (а то и сами разбирают типы полей как надо).

Или у вас ситуация когда тип у поля text а в нем дрова лежат (json например)? И эта информация ниоткуда ни очевидна кроме описания схемы БД внутри приложения?

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
03.09.2015, 12:01
    #39042278
Warstone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Таблица, из которой было взято поле.
Maxim Boguk,

Да, я могу вытащить типы из библиотеки. Но это не то... Рассмотрим случай (не придерайтесь к архитектуре хранения и т.д.):
Есть 2 таблицы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE img (
id BIGSERIAL NOT NULL PRIMARY KEY,
data BYTEA NOT NULL
);

CREATE TABLE img_meta (
id BEGSERIAL NOT NULL PRIMARY KEY,
data BYTEA NOT NULL
)

Допустим что в img.data хранится сама картинка (бинарь), а в img_meta.data хранится запакованный JSON с тегами и прочей информацией (знаю что не оптимально и вообще так делать вредно. Это просто пример).
Берем запрос:
Код: sql
1.
SELECT img.id, img.data AS img, img_meta.data AS meta FROM img LEFT JOIN img_meta ON img.id = img_meta.id

Будет 3 колонки, BIGINT, BYTEA, BYTEA. У меня где-то в приложении есть метаинформация об этих таблицах, где записано что это на самом деле BIGINT, XIMAGE, XZJSON. Однако сам ORM в общем случае не может понять что первый BYTEA - это XIMAGE, а второй - XZJSON. Драйвер ему об этом не скажет, ибо сам не знает. Он это может узнать только если будет знать откуда этим поля.

Понятно, что если работает математика, то определить это не представляется возможным (Кто его знает что там насчитал пользователь). Мы сейчас о простом случае.
...
Рейтинг: 0 / 0
03.09.2015, 12:06
    #39042290
Warstone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Таблица, из которой было взято поле.
Хотя сейчас почитал, возможно что
PQftable
PQftablecol - то что надо...
...
Рейтинг: 0 / 0
03.09.2015, 21:19
    #39042840
Warstone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Таблица, из которой было взято поле.
Накатал патчик для DBD::Pg:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
#!/usr/bin/perl

BEGIN {unshift @INC, '/home/warstone/DBD/Pg/dbdpg/blib/lib', '/home/warstone/DBD/Pg/dbdpg/blib/arch'}

use strict;
use warnings;
use DBI;
use DBD::Pg;
use Data::Dumper;

my $sql = "SELECT 1 AS one, i.id AS not_id, i.id + 1 AS wtf, i.ident AS jopa, il.level, il.max_items FROM inventory i LEFT JOIN inventory_level il ON i.id = il.inventory";

my $dbh = DBI->connect("dbi:Pg:dbname=farmstory", "farmstory", "", {AutoCommit => 1, RaiseError => 1});
my $sth = $dbh->prepare($sql);
$sth->execute;

my $data = $sth->pg_canonical_ids;
my $data2 = $sth->pg_canonical_names;

print "DBD::Pg version: $DBD::Pg::VERSION\nSQL: $sql\n\n";
print "Column names (\$sth->{NAME_lc}):\n" . Dumper($sth->{NAME_lc});
print "\nCanonical ids (\$sth->pg_canonical_ids, fast):\n". Dumper($data);
print "\nCanonical names (\$sth->pg_canonical_names, slow):\n" . Dumper($data2) . "\n";

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
warstone@dev:~/DBD/Pg/dbdpg$ perl test.pl
DBD::Pg version: 3.5.2
SQL: SELECT 1 AS one, i.id AS not_id, i.id + 1 AS wtf, i.ident AS jopa, il.level, il.max_items FROM inventory i LEFT JOIN inventory_level il ON i.id = il.inventory

Column names ($sth->{NAME_lc}):
$VAR1 = [
          'one',
          'not_id',
          'wtf',
          'jopa',
          'level',
          'max_items'
        ];

Canonical ids ($sth->pg_canonical_ids, fast):
$VAR1 = [
          undef,
          [
            24047,
            1
          ],
          undef,
          [
            24047,
            2
          ],
          [
            24055,
            3
          ],
          [
            24055,
            5
          ]
        ];

Canonical names ($sth->pg_canonical_names, slow):
$VAR1 = [
          undef,
          'public.inventory.id',
          undef,
          'public.inventory.ident',
          'public.inventory_level.level',
          'public.inventory_level.max_items'
        ];
Сейчас допричешу и попробую продавить на добавление в DBD::Pg.
...
Рейтинг: 0 / 0
10.09.2015, 04:00
    #39047578
Warstone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Таблица, из которой было взято поле.
Накатал ORM на коленке под это дело:
https://github.com/Warstone/SORM/blob/develop/test.pl

Наконец-то ОРМ, который сочетает (должен сочетать) в себе метаданные и дает тебе писать произвольный SQL запрос.
...
Рейтинг: 0 / 0
10.09.2015, 04:01
    #39047579
Warstone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Таблица, из которой было взято поле.
Пока-что хак на хаке и хаком погоняет. (Не использовать в продакшене ни в коем случае).
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Таблица, из которой было взято поле. / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]