Postgresのstored functionで2次元配列を引数にし,Pythonから呼び出す

How to call a Postgres stored function with an matrix as an argument from Python

あまりサンプルがなかったので,簡単なものを作成してみた。その2。
ここを参考にした。

  • Postgres 16
  • Python 12

二次元配列で数字のリストを渡して,ストアドファンクションで合計を計算し,返す

Postgresql


drop function if exists matfunc;
create function matfunc(mat integer[][])
returns integer as
$$
declare 
  res integer := 0;
  i integer;
  j integer;
begin

for i in array_lower(mat,1)..array_upper(mat,1) loop
  for j in array_lower(mat,2)..array_upper(mat,2) loop
    res := res + mat[i][j];
  end loop;
end loop;
return res;
end;
$$
language plpgsql;

select matfunc(ARRAY[ARRAY[1,2,3], ARRAY[4,5,6]]);

Python

import psycopg2

try:
    ps_connection = psycopg2.connect(user="username",
                                     password="password",
                                     host="127.0.0.1",
                                     port="5432",
                                     database="testdatabase")

    cursor = ps_connection.cursor()

    lst =[ [1,2,3],[4,5,6]]
    # call stored procedure
    cursor.execute('select matfunc(%s)', (lst,))

    result = cursor.fetchall()
    for row in result:
        print("sum = ", row[0], )

except (Exception, psycopg2.DatabaseError) as error:
    print("Error while connecting to PostgreSQL", error)

finally:
    # closing database connection.
    if ps_connection:
        cursor.close()
        ps_connection.close()
        print("PostgreSQL connection is closed")

Postgresのstored functionで配列を引数にし,Pythonから呼び出す

How to call a Postgres stored function with an array as an argument from Python

あまりサンプルがなかったので,簡単なものを作成してみた。

  • Postgres 16
  • Python 12

配列で数字のリストを渡して,ストアドファンクションで合計を計算し,返す

Postgresql


drop function if exists testfunc;
create function testfunc(ary integer[])
returns integer as
$$
declare tmp integer;
begin
select sum(s) into tmp from unnest(ary) as s;
return tmp;
end;
$$
language plpgsql;

select testfunc(ARRAY[1,2,3]);

Python

import psycopg2

try:
    ps_connection = psycopg2.connect(user="username",
                                     password="password",
                                     host="127.0.0.1",
                                     port="5432",
                                     database="testdatabase")

    cursor = ps_connection.cursor()

    lst = [1,2,3]
    # call stored procedure
    cursor.execute('select testfunc(%s)', (lst,))

    result = cursor.fetchall()
    for row in result:
        print("sum = ", row[0], )

except (Exception, psycopg2.DatabaseError) as error:
    print("Error while connecting to PostgreSQL", error)

finally:
    # closing database connection.
    if ps_connection:
        cursor.close()
        ps_connection.close()
        print("PostgreSQL connection is closed")

Raspberry PI4 でNextCloudを構築

概要

Dropbox,OneDrive,GoogleDrive,Boxなど色々アカウントを作って
便利に使っているのですが,無料アカウントだと容量が少ないのがネックとなります。
4つ持っていてもすぐに一杯になり,iPhone,iPadと連携して使う分にはすぐに
いっぱいになります。

そこで,オープンソースのNextCloudをRaspberryPIに入れて自宅でディスクストレージ
を構築することにします。

RaspberryPIの準備

RaspberryPI

先日たまたま秋葉原で見つけて購入したRaspberryPI4の4Gメモリ版を流用します。
Windows10を入れて使っていたのですが,如何せん重いのと,リモートで使うのには
不便なので,ここで一旦Linux化することにします。

raspbian os

Macを使っているのですが,公式サイトから,Raspberry Pi Imagerをダウンロードし
インストールします。SDカードを挿して,Raspberry Pi Imagerを起動,CHOOSE OSメニューの
otherからRaspberry Pi OS Liteを選択しインストールします。
ちなみにSDカードは32Gのものを使いましたが,OS入れただけだと2G程度の使用量です。

update

おきまりのアップデートをします

sudo apt udpate -y
sudo apt upgrade -y

リモート設定

sshログインできるように設定します

sudo raspi-config

3 Interface OptionsからP2 SSHを選択し YESを選択

ifconfig

このコマンドでIPアドレスを調べてリモートからログインできるようになりました

固定IPアドレス

固定にしないと面倒なので固定IPにします

sudo vi /etc/dhcpcd.conf
interface eth0
static ip_address=192.168.10.102/24
static routers=192.168.10.1
static domain_name_servers=192.168.10.1 8.8.8.8

こんな感じで追加しreboot

NextCloud

インストール

こちらを参考にインストールします。
インストールにはsnapというパッケージ管理システムを利用します。このコマンド一発で,MySQLなど必要なものが全てインストールから設定まで行ってくれます。

sudo apt install snapd
sudo snap install nextcloud

ルータの設定

外部からアクセスする関係上,ルータに穴を開けます。
80と443をこのRaspberryPIのIPアドレスにマッピングします

ダイナミックDNS

固定IPアドレスならば気にする必要ないのですが,プロバイダによってはダイナミックIPアドレスの場合があるので,SofteatherVPNをインストールした時に,設定したダイナミックDNSのホスト名を使用します。
vpn0000000000.softether.netといった感じのやつですね。

ユーザ追加

管理者を追加します。sudoでやるとパスエラーが出たので,Rootになってから実行しました

sudo su -
nextcloud.manual-install sammy password

エラーがいっぱい出ましたが,無事終了

ERROR: ld.so: object '/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
Nextcloud was successfully installed

Trusted Domains

sudo su -
nextcloud.occ config:system:get trusted_domains

先ほど設定したドメイン名も

nextcloud.occ config:system:set trusted_domains 1 --value=vpn00000000.softether.net
ERROR: ld.so: object '/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
System config value trusted_domains => 1 set to string vpn00000000.softether.net

仕上げ

SSLの設定

外部からアクセスするのでLet’s Encryptの無料SSLを入れます。

sudo su -
nextcloud.enable-https lets-encrypt
In order for Let's Encrypt to verify that you actually own the
domain(s) for which you're requesting a certificate, there are a
number of requirements of which you need to be aware:

1. In order to register with the Let's Encrypt ACME server, you must
   agree to the currently-in-effect Subscriber Agreement located
   here:

       https://letsencrypt.org/repository/

   By continuing to use this tool you agree to these terms. Please
   cancel now if otherwise.

2. You must have the domain name(s) for which you want certificates
   pointing at the external IP address of this machine.

3. Both ports 80 and 443 on the external IP address of this machine
   must point to this machine (e.g. port forwarding might need to be
   setup on your router).

Have you met these requirements? (y/n) y

yを入力します

Please enter an email address (for urgent notices or key recovery): 

メールアドレスを入力しEnter

Please enter your domain name(s) (space-separated): 

先ほど設定したダイナミックDNSのホスト名を入力

これでとりあえずはインストール完了です。

その他

そのほかとして

  • Apacheの設定をhttpからhttpsへのリダイレクト
  • linuxのApplicationFireWall設定など

いろいろセキュリティ絡みが残っているのですが,それはまた別の話。。。