Conversation

elprans

Add the new record_class parameter to the create_pool() and
connect() functions, as well as to the cursor(), prepare(),
fetch() and fetchrow() connection methods.

This not only allows adding custom functionality to the returned
objects, but also assists with typing (see #577 for discussion).

Fixes: #40.

@elpranselprans requested a review from 1st1 July 19, 2020 17:31
@elpranselprans force-pushed the record-class branch 2 times, most recently from 7d8361b to 0715bf8 Compare July 19, 2020 19:02
*args,
prefetch=None,
timeout=None,
record_class=None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding record_class everywhere I'd allow passing it to the constructor. Or add a set_record_class_factory method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any evidence that users want multiple different record types on one connection?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire impetus of this push was from #577, where the record_class is used as a TypeDict-like typehint for the result, which gets typechecked also.

I'd allow passing it to the constructor.

It is also allowed to be passed in the constructor if you want a connection-wide subclass.

@victoraugustolls

@elprans is this PR ok to be merged? I'm really looking forward for this and the typings PR 😄

Add the new `record_class` parameter to the `create_pool()` and
`connect()` functions, as well as to the `cursor()`, `prepare()`,
`fetch()` and `fetchrow()` connection methods.

This not only allows adding custom functionality to the returned
objects, but also assists with typing (see #577 for discussion).

Fixes: #40.
@elpranselprans merged commit db4f1a6 into master Aug 15, 2020
@victoraugustollsvictoraugustolls mentioned this pull request Aug 15, 2020
@ponomar

@elprans Can you provide an example how to implement custom record_class with dot-notation?
Because it's unclear from the docs. I think it would be very useful for many people. Thanks!

@CaerDarrow

@elprans Can you provide an example how to implement custom record_class with dot-notation?
Because it's unclear from the docs. I think it would be very useful for many people. Thanks!

Not sure if this is correct but should work

    class MyRecord(Record):
        def __getattr__(self, item):
            return self.get(item)

@jparise

#960 adds an example of this to the FAQ item.

@ofer-pd

I tried implementing that example, but I kept getting errors from the GraphQL execution engine because it passed __await__ (via hasattr()) and received None — based on my reading of the docs, you're supposed to raise AttributeError if the lookup fails:

https://docs.python.org/3/reference/datamodel.html#object.__getattr__

So I updated the code to this, and it started working:

class AttrRecord( asyncpg.Record ):
    def __getattr__( self, name ):
        if name not in self:
            raise AttributeError
        return self[ name ]

Sign up for free to join this conversation on . Already have an account? Sign in to comment
None yet
None yet

Successfully merging this pull request may close these issues.

Add ability to set the Record factory on the connection