Abstraction level at which to create SQLAlchemy ORM object

Cameron Simpson cs at cskk.id.au
Thu Feb 10 18:59:46 EST 2022


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.

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Python-list mailing list