Abstraction level at which to create SQLAlchemy ORM object

Loris Bennett loris.bennett at fu-berlin.de
Fri Feb 11 02:05:24 EST 2022


Hi Cameron,

Cameron Simpson <cs at cskk.id.au> writes:

> On 10Feb2022 14:14, Loris Bennett <loris.bennett at fu-berlin.de> wrote:
>>I am writing a command line program which will modify entries in a
>>database and am trying out SQLAlchemy.
>>
>>A typical command might look like
>>
>>  um --operation add --uid ada --gid coders --lang en
>>
>>Parsing the arguments I get, ignoring the operation, a dict
>>
>>  {uid: "ada", gid: "coders", lang: "en"}
>>
>>At some point this needs to be converted into an object of the class User:
>>
>>  class User(Base):
>>      __tablename__ = "users"
>>
>>      uid = Column('uid', String, primary_key=True)
>>      gid = Column('gid', String)
>>      lang = Column('lang', String)
>>
>>In a way it seems it would be economical to do the conversion as early
>>as possible, so I can just pass around User objects.  However, this
>>would mean that the entry point for the program would already be tightly
>>coupled to the specifics of the database interaction.
>>
>>On the other hand, delaying the conversion would mean probably having to
>>define my own User class, which seems like unnecessary overhead.  It
>>would have the advantage that I could ditch SQLAlchemy more easily if I
>>find it too mind-bending.
>
> If the entire persistent state of the user lives in the db I'd just 
> define the User ORM type and give it whatever methods you need. So 
> exactly what you've got above.
>
> It is close to the db, but if you only interact via the methods and the 
> core attributes/columns that should be mostly irrelevant to you.
>
> If you're concerned about switching backends, maybe define an 
> AbstractUser abstract class with the required methods. Then you can at 
> least ensure method coverage if you make another backend:
>
>     class AbstractUser(ABC):
>         @abstractmethod
>         def some_user_method(self,...):
>
>
>     class SQLAUser(Base, AbstractUser):
>         ... your SQLA ORM User class above ...
>
>     User = SQLAUser
>
>     ... everything else just talks about user ...
>
> But you can do all of that _later_, only needed if you decide to change 
> backends in a controlled manner.

Thanks for reminding me about abstract classes, but more importantly
that I can do this kind of stuff later. 

Cheers,

Loris




More information about the Python-list mailing list