40.1. PL/Python ÇÔ¼ö

PL/Python·Î ÀÛ¼ºµÈ ÇÔ¼ö´Â Ç¥ÁØÀÇ CREATE FUNCTION ±¸¹®À¸·Î ¼±¾ðµË´Ï´Ù.

CREATE FUNCTION 
funcname
 (
argument-list
)
  RETURNS 
return-type

AS $$
  # PL/Python function body
$$ LANGUAGE plpythonu;

ÇÔ¼ö º»Ã¼´Â ´Ü¼øÇÑ Python ½ºÅ©¸³Æ®ÀÔ´Ï´Ù. ÇÔ¼ö°¡ ºÒ·Á °¡¸é, ÀÎÀÚ´Â args[]¹è¿­ÀÇ ¿ä¼Ò·Î¼­ ¶Ç, À̸§ ÷ºÎÀÇ ÀÎÀÚ´Â Åë»óÀÇ º¯¼ö·Î¼­ Python ½ºÅ©¸³Æ®¿¡°Ô °Ç³×Áý´Ï´Ù. °á°ú´Â, Python ÄÚµå·ÎºÎÅÍ Åë»óÀÇ ¹æ¹ý, return ¶Ç´Â yield(°á°ú ¼¼Æ®Äõ¸® °æ¿ì)·Î µ¹·ÁÁÖ¾îÁö´Â °ÍÀÔ´Ï´Ù.

¿¹¸¦ µé¾î, 2°³ÀÇ Á¤¼ö Áß Å« ¼ö¸¦ µ¹·ÁÁÖ´Â ÇÔ¼ö´Â ÀÌÇÏ¿Í °°ÀÌ Á¤ÀÇÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

CREATE FUNCTION pymax (a integer, b integer)
  RETURNS integer
AS $$
  if a > b:
    return a
  return b
$$ LANGUAGE plpythonu;

ÇÔ¼ö Á¤ÀÇÀÇ º»Ã¼·Î¼­ Á¦°øµÈ PythonÀÇ ÄÚµå´Â PythonÀÇ ÇÔ¼ö¿¡ º¯È¯µË´Ï´Ù. ¿¹¸¦ µé¸é À§ÀÇ ¿¹´Â ÀÌÇÏ¿Í °°ÀÌ µË´Ï´Ù.

def __plpython_procedure_pymax_23456():
  if a > b:
    return a
  return b

¿©±â¼­, 23456Àº PostgreSQL¿¡ ÀÇÇØ ÇÒ´çÇÒ ¼ö ÀÖ´ø ÀÌ ÇÔ¼öÀÇ OIDÀÔ´Ï´Ù.

PostgreSQLÇÔ¼ö ¸Å°³º¯¼ö´Â args±Û·Î¹ú ¸®½ºÆ®·ÎºÎÅÍ ÀÌ¿ë °¡´ÉÇÕ´Ï´Ù. pymax¸¦ ¿¹·Î Çϸé, args[0]¿¡´Â ÃÖÃÊÀÇ ÀÎÀڷμ­ °Ç³×¹ÞÀº °ÍÀÌ Æ÷ÇԵǾî args[1]¿¡´Â 2¹øÂ°ÀÇ ÀÎÀÚÀÇ °ªÀÌ Æ÷ÇԵ˴ϴÙ. ´Ù¸¥ ¹æ¹ýÀ¸·Î¼­ À§ÀÇ ¿¹¿Í °°°Ô À̸§ ÷ºÎ ¸Å°³º¯¼ö¸¦ »ç¿ëÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. À̸§ ÷ºÎ ¸Å°³º¯¼ö¸¦ »ç¿ëÇÏ´Â °ÍÀ¸·Î Åë»ó °¡µ¶¼ºÀÌ ´õÇÕ´Ï´Ù.

SQLÀÇ NULL°ªÀÌ ÇÔ¼ö¿¡ °Ç³×Áö¸é, ±× ÀÎÀÚ°ªÀº Python. ±×·³ None°¡ µË´Ï´Ù. À§ÀÇ ÇÔ¼ö Á¤ÀÇ¿¡¼­´Â, NULL ÀÔ·ÂÀ¸·Î´Â À߸øÇÑ °á°ú°¡ µ¹·ÁÁÖ¾îÁý´Ï´Ù. ÇÔ¼ö Á¤ÀÇ¿¡ STRICT¸¦ ºÎ¿©ÇØ PostgreSQL¸¦, NULL°ª°¡ °Ç³×¹Þ¾ÒÀ» °æ¿ì¿¡ ±× ÇÔ¼ö¸¦ È£ÃâÇÏÁö ¾Ê°í, ÀÚµ¿ÀûÀ¸·Î ´ÜÁö NULL °á°ú¸¦ µ¹·ÁÁÖ´Â, º¸´Ù ÀÌ»óÀûÀÎ µ¿ÀÛÀÌ °¡´É ÇÕ´Ï´Ù. ±× ¹Û¿¡, ÇÔ¼ö º»Ã¼·Î NULL ÀÔ·ÂÀ» °Ë»çÇÒ ¼öµµ ÀÖ½À´Ï´Ù.

CREATE FUNCTION pymax (a integer, b integer)
  RETURNS integer
AS $$
  if (a is None) or (b is None):
    return None
  if a > b:
    return a
  return b
$$ LANGUAGE plpythonu;

À§¿¡¼­ °¡¸®Å² °Íó·³, PL/Python ÇÔ¼ö·ÎºÎÅÍ SQL NULL°ªÀ» µ¹·ÁÁÖ·Á¸é, None¶ó´Â °ªÀ» µ¹·ÁÁÖ¼¼¿ä. ÇÔ¼ö¸¦ ¾ö¹ÐÇÏ°Ô Çϰųª ÇÏÁö ¾Ê´Â °æ¿ì¿¡¼­µµ, À̰ÍÀ» ½Ç½ÃÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

º¹ÇÕÇüÀÇ ÀÎÀÚ´Â PythonÀÇ ¸ÊÀ¸·Î¼­ °Ç³×¹Þ½À´Ï´Ù. ¸ÊÀÇ ¿ä¼Ò¸íÀº º¹ÇÕÇüÀÇ ¼Ó¼º¸íÀÔ´Ï´Ù. °Ç³×¹ÞÀº ÇàÀÇ ¼Ó¼º°ªÀÌ NULLÀÇ °æ¿ì, ¸Ê»ó¿¡¼­´Â None¶ó°í ÇÏ´Â °ªÀÌ µË´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE TABLE employee (
  name text,
  salary integer,
  age integer
);

CREATE FUNCTION overpaid (e employee)
  RETURNS boolean
AS $$
  if e["salary"] > 200000:
    return True
  if (e["age"] < 30) and (e["salary"] > 100000):
    return True
  return False
$$ LANGUAGE plpythonu;

Python ÇÔ¼ö·ÎºÎÅÍ Çà ¶Ç´Â º¹ÇÕÇüÀ» µ¹·ÁÁÖ´Â ¹æ¹ýÀº º¹¼ö Á¸ÀçÇÕ´Ï´Ù. ÀÌÇÏÀÇ ¿¹¿¡¼­´Â

CREATE TYPE named_value AS (
  name   text,
  value  integer
);

º¹ÇÕÇüÀÇ °á°ú´Â ÀÌÇÏ¿Í °°ÀÌ µ¹·ÁÁÖ¾îÁý´Ï´Ù.

¼ø¼­Çü(Æ©Çà ¶Ç´Â ¸®½ºÆ®)ÇüÅÂset ´Â ºÒ°¡(ÀÎ DECºÎ¸¦ ÇÒ ¼ö ¾ø±â ¶§¹®¿¡)

¹ÝȯµÇ´Â ½ÃÄö½º °´Ã¼´Â, °á°úÀÇ º¹ÇÕÇüÀÌ °¡Áö´Â Çʵå¿Í °°Àº Ç׸ñ¼öµµ °°¾Æ¾ßÇÕ´Ï´Ù. 0À̶ó°í ÇÏ´Â À妽ºÀÇ Ç׸ñÀÌ º¹ÇÕÇüÀÇ ÃÖÃÊÀÇ Çʵå, 1ÀÌ ´ÙÀ½ÀÇ Çʵå, , , µË´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  return [ name, value ]
  # or alternatively, as tuple: return ( name, value )
$$ LANGUAGE plpythonu;

ÀÓÀÇÀÇ ¿­·Î SQL NULL°ª¸¦ µ¹·ÁÁÖ·Á¸é, ´ëÀÀÇÏ´Â À§Ä¡¿¡ None¸¦ »ðÀÔÇÕ´Ï´Ù

¸Ê(»çÀü)

°á°úÇüÀÇ ¿­ÀÇ °ªÀº, ·Ä¸íÀ» Ű·Î¼­ °¡Áö´Â ¸ÊÀ¸·ÎºÎÅÍ ²¨³»Áý´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  return { "name": name, "value": value }
$$ LANGUAGE plpythonu;

ºÒÇÊ¿äÇÑ »çÀüÀÇ Å°¿Í °ªÀÇ ½ÖÀº ¹«½ÃµË´Ï´Ù. Á¸ÀçÇÏÁö ¾Ê´Â Ű´Â ¿¡·¯·Î¼­ ´Ù·ç¾îÁý´Ï´Ù. ÀÓÀÇÀÇ ¿­·Î SQL NULL¸¦ µ¹·ÁÁÖ±â À§Çؼ­´Â, ´ëÀÀÇÏ´Â ·Ä¸íÀ» Ű·Î¼­ None¸¦ »ðÀÔÇØ ÁÖ¼¼¿ä.

°´Ã¼(__getattr__¹æ¹ýÀ» Á¦°øÇÏ´Â ÀÓÀÇÀÇ °´Ã¼)

À̰ÍÀº ¸Ê°ú °°ÀÌ µ¿ÀÛÇÕ´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  class named_value:
    def __init__ (self, n, v):
      self.name = n
      self.value = v
  return named_value(name, value)

  # or simply
  class nv: pass
  nv.name = name
  nv.value = value
  return nv
$$ LANGUAGE plpythonu;

¹Ýȯ°ªÀ» ÁغñÇϰí ÀÖÁö ¾Ê´Â °æ¿ì, Python´Â ±âº»°ªÀÇ None¸¦ µ¹·ÁÁÝ´Ï´Ù. PL/Python´Â, PythonÀÇ None¸¦ SQLÀÇ NULL°ª·Î º¯È¯ÇÕ´Ï´Ù.

¶Ç, PL/PythonÇÔ¼ö´Â ½ºÄ®¶ó ¶Ç´Â º¹ÇÕÇüÀÇ ÁýÇÕÀ» µ¹·ÁÁÙ ¼öµµ ÀÖ½À´Ï´Ù. µ¹·ÁÁÖ¾îÁö´Â °´Ã¼´Â ³»ºÎÀûÀ¸·Î ÀÌÅÍ·¹ÀÌÅÍ(iterator)¿¡ º¯È¯µÇ±â ¶§¹®¿¡, º¹¼öÀÇ ½ÇÇö ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ÀÌÇÏÀÇ ¿¹¿¡¼­´Â, ÀÌÇÏÀÇ º¹ÇÕÇüÀÌ Á¸ÀçÇÏ´Â °ÍÀ» °¡Á¤ÇÕ´Ï´Ù.

CREATE TYPE greeting AS (
  how text,
  who text
);

ÁýÇÕÀ̶ó´Â °á°ú´Â ÀÌÇϷκÎÅÍ µ¹·ÁÁÖ¾îÁý´Ï´Ù.

¼ø¼­Çü(Æ©ÇÃ, ¸®½ºÆ®, ¼¼Æ®)

CREATE FUNCTION greet (how text)
  RETURNS SETOF greeting
AS $$
  # return tuple containing lists as composite types
  # all other combinations work also
  return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] )
$$ LANGUAGE plpythonu;

iterator(__iter__¹æ¹ý°ú next ¹æ¹ýÀ» Á¦°øÇÏ´Â ÀÓÀÇÀÇ °´Ã¼)

CREATE FUNCTION greet (how text)
  RETURNS SETOF greeting
AS $$
  class producer:
    def __init__ (self, how, who):
      self.how = how
      self.who = who
      self.ndx = -1

    def __iter__ (self):
      return self

    def next (self):
      self.ndx += 1
      if self.ndx == len(self.who):
        raise StopIteration
      return ( self.how, self.who[self.ndx] )

  return producer(how, [ "World", "PostgreSQL", "PL/Python" ])
$$ LANGUAGE plpythonu;

Á¦³×·¹ÀÌÅÍ(yield)

CREATE FUNCTION greet (how text)
  RETURNS SETOF greeting
AS $$
  for who in [ "World", "PostgreSQL", "PL/Python" ]:
    yield ( how, who )
$$ LANGUAGE plpythonu;

Warning

Çö½ÃÁ¡¿¡¼­´Â, Python bug #1483133À̱⠶§¹®¿¡, ÀϺÎÀÇ Python 2.4 µð¹ö±×ÆÇ(--with-pydebug¿É¼Ç ÷ºÎ·Î ¼³Á¤/ÄÄÆÄÀÏ µÈ Python)ÀÌ, ÁýÇÕ °á°ú¸¦ µ¹·ÁÁÖ±â À§Çؼ­ ÀÌÅ×·¹ÀÌÅ͸¦ »ç¿ëÇÏ´Â °æ¿ì¿¡´Â PostgreSQL¼­¹ö¸¦ Å©·¡½¬ ½ÃŰ´Â °ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù. ¹ÌÄ¡°ªÀÇ Fedora 4¿¡´Â ÀÌ·± ºÒÆíÀÌ ÀÖ½À´Ï´Ù. Python ¿î¿ëÆÇÀ̳ª ÆÐÄ¡ Àû¿ëÀÌ ³¡³­ Fedora 4¿¡¼­´Â ÀÌ ¹®Á¦´Â ÀϾÁö ¾Ê½À´Ï´Ù.

±Û·Î¹úÀÎ SD»çÀüÀº, ÇÔ¼ö È£Ãâ°£ÀÇ µ¥ÀÌÅÍ º¸Á¸À» À§ÇØ »ç¿ëÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ÀÌ º¯¼ö´Â »çÀûÀÎ Á¤Àû µ¥ÀÌÅÍÀÔ´Ï´Ù. ±Û·Î¹úÀÎ GD»çÀüÀº, °øÀ¯ µ¥ÀÌÅÍÀ̸ç, ¼¼¼Ç³»ÀÇ ¸ðµç Python ÇÔ¼ö·Î »ç¿ëÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ÁÖÀÇÇØ »ç¿ëÇØ ÁÖ¼¼¿ä.

°¢ ÇÔ¼ö´Â, Python interpreter³»¿¡¼­ ÀÚ½ÅÀÇ ½ÇÇà ȯ°æÀ» ÀÔ¼öÇÕ´Ï´Ù. ±× ¶§¹®¿¡, myfunc¿¡ ÀÇÇÑ ±Û·Î¹ú µ¥ÀÌÅÍ¿Í ÇÔ¼öÀÇ ÀÎÀÚ´Âmyfunc2·ÎºÎÅÍ »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù. »ó±â·Î ¼³¸íÇÑ ´ë·Î, GD»çÀü ³»ÀÇ µ¥ÀÌÅÍ´Â ¿¹¿ÜÀÔ´Ï´Ù.