Before proceeding with the following steps, ensure you have set up a new environment on your system with a custom Python virtual environment located at /scratch/venv/envs/p310
. For additional setup instructions, refer to apps.md.
Follow these steps to get everything working from scratch:
Run the following commands to install PostgreSQL and the plpython3u
extension:
sudo apt update
sudo apt install postgresql-plpython3-14
To enable plpython3u
in a specific database (e.g., test
), first log into PostgreSQL:
sudo -u postgres psql
Then, create your test database (if it doesn’t already exist) and enable the extension:
CREATE DATABASE test;
\connect test
CREATE EXTENSION plpython3u;
Exit the psql
interface:
\q
To facilitate authentication, create a PostgreSQL user matching your Linux system user.
Open the PostgreSQL shell as the postgres
superuser:
sudo -u postgres psql
Create the PostgreSQL user fkariminej
with superuser privileges:
CREATE USER fkariminej WITH SUPERUSER CREATEDB CREATEROLE;
Exit the shell:
\q
From now on, you can directly access the database with the following command:
psql -U fkariminej -d test
Make sure the postgres
user has access to your home directory and the relevant paths:
sudo chmod o+rx /home/fkariminej
sudo chmod o+rx /scratch
sudo chmod o+rx /scratch/venv
sudo chmod o+rx /scratch/venv/envs
sudo chmod o+rx /scratch/venv/envs/p310
Open a new shell script file for PostgreSQL:
vi /scratch/pg_service.sh
Add the following lines to set the PYTHONPATH
and PYTHONUSERBASE
for your virtual environment:
#!/bin/bash
export PGDATABASE=test
export PGUSER=fkariminej
export PGPORT=5432
export PATH=/usr/lib/postgresql/14/bin:$PATH
export PYTHONUSERBASE=/scratch/venv/envs/p310
export PYTHONPATH=/scratch/venv/envs/p310/lib/python310.zip:/scratch/venv/envs/p310/lib/python3.10:/scratch/venv/envs/p310/lib/python3.10/lib-dynload:/scratch/venv/envs/p310/lib/python3.10/site-packages
# Start PostgreSQL using the correct configuration file
pg_ctl -D /etc/postgresql/14/main -l /var/lib/postgresql/14/main/postgres_logfile start
chmod +x /scratch/pg_service.sh
sudo touch /var/lib/postgresql/14/main/postgres_logfile
sudo chown postgres:postgres /var/lib/postgresql/14/main/postgres_logfile
sudo systemctl stop [email protected]
You can find the services:
systemctl list-units --type=service | grep postgresql
sudo -u postgres /scratch/pg_service.sh
After running the script, verify the setup:
psql -U fkariminej -d test
Create a PL/Python function and run it to ensure everything works:
CREATE OR REPLACE FUNCTION pymtorch()
RETURNS float8 AS $$
import sys
import torch
x = torch.Tensor([1, 3]) * torch.Tensor([4, 3]).to(torch.float32)
return float(x.sum())
$$ LANGUAGE plpython3u;
SELECT pymtorch();
To avoid manually stopping and restarting PostgreSQL every time the machine starts, create a new service:
sudo vi /etc/systemd/system/newpostgres.service
[Unit]
Description=Custom PostgreSQL Service using /scratch/pg_service.sh
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c "sudo systemctl stop [email protected] && sudo -u postgres /scratch/pg_service.sh"
ExecStop=/bin/bash -c "sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /etc/postgresql/14/main stop"
User=fkariminej
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable newpostgres.service
sudo systemctl start newpostgres.service
sudo systemctl status newpostgres.service
If issues arise, clean up any leftover files:
sudo rm -f /var/lib/postgresql/14/main/postmaster.pid
sudo rm -f /var/run/postgresql/.s.PGSQL.5432
sudo lsof -i :5432
ps aux | grep postgres
sudo kill -9 <PID>
sudo systemctl enable newpostgres.service
The
[email protected]
is located in/lib/systemd/system/{[email protected], postgresql.service}
. Their symbolic links are found here:
'/etc/systemd/system/multi-user.target.wants/[email protected]' -> '/lib/systemd/system/[email protected]'
/etc/systemd/system/multi-user.target.wants/postgresql.service -> /lib/systemd/system/postgresql.service
/usr/lib/postgresql/14/bin
/var/lib/postgresql/14/main # owner:group -> postgres:postgres
/etc/postgresql/14/main # pg_ctl.conf -> owner:group postgres:postgres
/*
multiple comments
*/
CREATE DATABASE test;
DROP DATABASE test;
\connect test
CREATE EXTENSION plpython3u;
CREATE USER fkariminej WITH SUPERUSER CREATEDB CREATEROLE;
SHOW data_directory; -- PGDATA SHOW data_directory;
SELECT current_user; -- PGUSER here fkariminej
SELECT current_database(); -- PGDATABASE here test
-- A specific function (e.g. my_func), a specific schema (e.g., my_schema)
SELECT my_func(); -- Run the function
DROP FUNCTION my_func; -- Remove a function
DROP FUNCTION my_func(integer, text); -- Remove a function with parameter
DROP FUNCTION my_schema.my_func; -- Remove a function exists in a specific schema
DROP FUNCTION IF EXISTS my_func;
-- Print the definition of a function
SELECT pg_get_functiondef(oid)
FROM pg_proc
WHERE proname = 'my_func';
-- Print the definition of a function with Schema Context
SELECT pg_get_functiondef(p.oid)
FROM pg_proc p
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE p.proname = 'my_func' AND n.nspname = 'my_schema';
-- Output the function definition in a file
\o output_file.sql
SELECT pg_get_functiondef(oid)
FROM pg_proc
WHERE proname = 'my_func';
\o
\q -- Exit
sudo -u postgres psql
sudo -u postgres /scratch/pg_service.sh
psql -U fkariminej -d test