отладка postgresql триггер

Код для np.diagonal:

return asanyarray(a).diagonal(offset=offset, axis1=axis1, axis2=axis2)

То есть сначала он пытается преобразовать аргумент в массив, например, если это список списков. Но это не правильный способ превратить разреженную матрицу в ndarray.

In [33]: from scipy import sparse                                               
In [34]: M = sparse.csr_matrix(np.eye(3))                                       
In [35]: M                                                                      
Out[35]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 3 stored elements in Compressed Sparse Row format>
In [36]: M.A                                  # right                                  
Out[36]: 
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
In [37]: np.asanyarray(M)                    # wrong                           
Out[37]: 
array(<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 3 stored elements in Compressed Sparse Row format>, dtype=object)

Правильный способ использования np.diagonal:

In [38]: np.diagonal(M.A)                                                       
Out[38]: array([1., 1., 1.])

Но в этом нет необходимости. M уже имеет метод diagonal:

In [39]: M.diagonal()                                                           
Out[39]: array([1., 1., 1.])

np.sum действительно работает, потому что он делегирует действие методу (посмотрите его код):

In [40]: M.sum(axis=0)                                                          
Out[40]: matrix([[1., 1., 1.]])
In [41]: np.sum(M, axis=0)                                                      
Out[41]: matrix([[1., 1., 1.]])

Как правило, старайтесь использовать sparse функции и методы на разреженных матрицах. Не рассчитывайте, что функции numpy будут работать правильно. sparse построен на numpy, но numpy не «знает» о sparse.

26
задан Dave Vogt 20 November 2008 в 18:54
поделиться

3 ответа

  1. Использование следующий код в триггерной функции, затем наблюдайте вкладку 'сообщений' в pgAdmin3 или вывод в psql:

    RAISE NOTICE 'myplpgsqlval is currently %', myplpgsqlval;       -- either this
    RAISE EXCEPTION 'failed';  -- or that
    
  2. Для наблюдения, какие триггеры на самом деле называют, сколько раз и т.д., следующее утверждение является предпочтительным спасителем:

    EXPLAIN ANALYZE UPDATE table SET foo='bar'; -- shows the called triggers
    

    Примечание, что, если Ваш триггер не становится названным и Вы используете наследование, может случиться так, что Вы только определили триггер на родительской таблице, тогда как триггеры не наследованы дочерними таблицами автоматически.

  3. Для продвижения через функцию можно использовать отладчик, встроенный в pgAdmin3, который в Windows включен по умолчанию; все, что необходимо сделать, выполняют код, найденный в [1 110]...\8.3\share\contrib\pldbgapi.sql против базы данных Вы отлаживаете, перезапускаете pgAdmin3, щелкаете правой кнопкой по своей триггерной функции, поражаете 'Точку останова Набора', и затем выполняете оператор, который заставил бы триггер стрелять, такие как оператор UPDATE выше.

54
ответ дан 28 November 2019 в 06:41
поделиться

Можно использовать 'операторы' уведомления повышения в триггерной функции для отладки его. Отладить триггер, не будучи названным вообще - другая история.

, Если Вы добавляете 'исключение повышения' в Вашей триггерной функции, может, Вы все еще сделать вставляете/обновляете?

кроме того, если Ваш тест обновления происходит в той же транзакции, поскольку Ваш тест вставки, теперь () будет тем же (так как это только вычисляется однажды на транзакцию), и поэтому обновление, будет казаться, ничего не сделает. Если это так, или сделайте их в отдельных транзакциях, или если это - модульный тест, и Вы не можете сделать этого, использовать clock_timestamp ().

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

ALTER TABLE documents
   ALTER COLUMN modification_time SET DEFAULT clock_timestamp();

Тогда в триггере, используйте "набор modification_time = значение по умолчанию".

Поэтому обычно это не делает дополнительного вычисления, но во время модульного теста это позволяет мне делать, вставляет с pg_sleep, промежуточным, чтобы моделировать время, передавая и на самом деле иметь это быть отраженным в данных.

3
ответ дан 28 November 2019 в 06:41
поделиться

Оказывается, что я использовал наследование в вышеупомянутой проблеме и забыл упоминать его. Теперь для всех, кто мог бы столкнуться с этим также, вот некоторые подсказки отладки:

Использование следующий код для отладки то, что делает триггер:

RAISE NOTICE 'test';       -- either this
RAISE EXCEPTION 'failed';  -- or that

Для наблюдения, какие триггеры на самом деле называют, сколько раз и т.д., следующее утверждение является предпочтительным спасителем:

EXPLAIN ANALYZE UPDATE table SET foo='bar'; -- shows the called triggers

Тогда существует одна вещь, которую я не знал прежде: триггеры только стреляют при обновлении точной таблицы, на которой они определяются. При использовании наследования НЕОБХОДИМО определить их на дочерних таблицах также!

4
ответ дан 28 November 2019 в 06:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: