Обсуждение: Can't register python class for domain?

Поиск
Список
Период
Сортировка

Can't register python class for domain?

От
"W. Matthew Wilson"
Дата:
I created this domain:

    create domain milliamp as double precision check (value >= 0);

Then when I register a python class named Milliamp, it never gets
used!  I think the problem is related to the type code coming back as
the underlying double precision type:

    >>> cursor.execute("select 4444::milliamp as m")
    >>> cursor.description[0][1]
    701
    >>> cursor.execute("select 4444::double precision as f")
    >>> cursor.description[0][1]
    701

But there really is a type called milliamp in postgresql, I promise:

    > select typname, oid from pg_type where typname in ('float8', 'milliamp');
    typname   oid
    -------- ------
    float8      701
    milliamp 949531
    (2 rows)

I found this code, and it suggests other people have run into this same problem:

https://github.com/beyang/psycopg2/blob/master/sandbox/domainoid.py

Any ideas what is going on?

Thanks in advance.  I love psycopg!


Re: Can't register python class for domain?

От
Adrian Klaver
Дата:
On 01/23/2015 07:16 AM, W. Matthew Wilson wrote:
> I created this domain:
>
>      create domain milliamp as double precision check (value >= 0);
>
> Then when I register a python class named Milliamp, it never gets
> used!  I think the problem is related to the type code coming back as
> the underlying double precision type:
>
>      >>> cursor.execute("select 4444::milliamp as m")
>      >>> cursor.description[0][1]
>      701
>      >>> cursor.execute("select 4444::double precision as f")
>      >>> cursor.description[0][1]
>      701
>
> But there really is a type called milliamp in postgresql, I promise:
>
>      > select typname, oid from pg_type where typname in ('float8', 'milliamp');
>      typname   oid
>      -------- ------
>      float8      701
>      milliamp 949531
>      (2 rows)
>
> I found this code, and it suggests other people have run into this same problem:
>
> https://github.com/beyang/psycopg2/blob/master/sandbox/domainoid.py
>
> Any ideas what is going on?

Hard to say with out seeing the code where you create and register the
milliamp type in psycopg2.

>
> Thanks in advance.  I love psycopg!
>
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: Can't register python class for domain?

От
Daniele Varrazzo
Дата:
On Fri, Jan 23, 2015 at 3:16 PM, W. Matthew Wilson <matt@tplus1.com> wrote:
> I created this domain:
>
>     create domain milliamp as double precision check (value >= 0);
>
> Then when I register a python class named Milliamp, it never gets
> used!  I think the problem is related to the type code coming back as
> the underlying double precision type:
>
>     >>> cursor.execute("select 4444::milliamp as m")
>     >>> cursor.description[0][1]
>     701
>     >>> cursor.execute("select 4444::double precision as f")
>     >>> cursor.description[0][1]
>     701
>
> But there really is a type called milliamp in postgresql, I promise:
>
>     > select typname, oid from pg_type where typname in ('float8', 'milliamp');
>     typname   oid
>     -------- ------
>     float8      701
>     milliamp 949531
>     (2 rows)
>
> I found this code, and it suggests other people have run into this same problem:
>
> https://github.com/beyang/psycopg2/blob/master/sandbox/domainoid.py
>
> Any ideas what is going on?

Yes, I've found that too. Although domains have an oid of their own,
unlike types, the libpq returns the oid of their base type instead. I
googled about that some times ago and found a laconic conversation
with someone making this question and Tom Lane answering "yes, that's
how it is" (the further question of the OP "will it be fixed" got
ignored).

So I'm afraid I don't know how to help with that: it seems the libpq
doesn't give enough information to the client.

-- Daniele


Re: Can't register python class for domain?

От
"W. Matthew Wilson"
Дата:
Here's the class I want to register:

    class Milliamp(numbers.Real):

         def __init__(self, val):
            self.val = val

        @classmethod
        def adapt_from_pg(cls, value, cursor):

            log.debug("Inside adapt_from_pg and value is {0}.".format(value))

            if value is None:
                return

            else:
                return cls(value)

Here's how I try to register it:

    from dazzle.dazzletypes import Milliamp

    MILLIAMP = psycopg2.extensions.new_type(
        (milliamp_oid, ),
        "milliamp",
        Milliamp.adapt_from_pg)

    psycopg2.extensions.register_type(MILLIAMP)

I look up the milliamp OID by querying the pg_type table:

    > select typname, oid from pg_type where typname in ('float8', 'milliamp');
    typname   oid
    -------- ------
    float8      701
    milliamp 949531
    (2 rows)


Re: Can't register python class for domain?

От
"W. Matthew Wilson"
Дата:
Thanks for the reply!  Glad to know it can not be done, so I will stop trying.

Maybe this will be the moment when I decide to contribute to postgresql :)