question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: A more concise API for overriding field arguments and consolidating TableSchema and ModelSchema

See original GitHub issue

Status quo

Users often need to provide overrides to autogenerated fields. There are currently two current mechanisms for this.

You can use field_for. This gets verbose when you use it for many fields.

class ArtistSchema(ModelSchema):
    class Meta:
        model = models.Artist

    created_at = field_for(models.Artist, "created_at", dump_only=True)
    # ...

You can also pass overrides on the model.

class Artist(Model):
    created_at = Column(Timestamp, info={"marshmallow": {"dump_only": True})

This awkwardly mixes concerns and can be problematic when you need multiple schemas for the same model.

Proposed changes

  1. Deprecate ModelSchema and TableSchema in favor of a SQLAlchemyAutoSchema that can take either model or table as an option. Like ModelSchema and TableSchema, SQLAlchemyAutoSchema will autogenerate fields for all columns. Field configuration can be overridden using a new auto_field function.
from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field

class ArtistSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = models.Artist
        # OR
        # table = models.Artist.__table__
     
    id = auto_field(dump_only=True)
    created_at = auto_field(dump_only=True)
  1. Add a SQLAlchemySchema class that associates the schema with a model/table so that auto_field can be used. Unlike SQLAlchemyAutoSchema, fields won’t be automatically generated for all columns, so fields must be declared explicitly.
from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field

class ArtistSchema(SQLAlchemySchema):
    class Meta:
        model = models.Artist
        # OR
        # table = models.Artist.__table__

    id = auto_field(dump_only=True)
    created_at = auto_field(dump_only=True)
    name = auto_field()
  1. Deprecate support for info={"marshmallow": {...}}, as it is redundant.

h/t @taion for the SQLAlchemySchema/auto_field idea and its implementation (currently outside this repo)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:15 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
sloriacommented, Feb 4, 2020

We have an implementation of this at work in a closed-source repo. It will take a bit of finagling to get it ready for upstream, but hopefully we’ll get to it…soon (sorry I can’t give an accurate estimate).

1reaction
sloriacommented, Aug 30, 2019

Is there an advantage to making this a separate class rather than a Meta option?

Not a huge advantage. My rationale is that SQLAlchemySchema and SQLAlchemyAutoSchema behave differently with regards to how they construct the schema at class declaration time. This is unlike the Meta options, e.g. ordered and render_module, which change the behavior of instances. This is a low-confidence opinion.

Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found