Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: using SQL Expression Language table definitions #356

Open
meshantz opened this issue Nov 24, 2020 · 2 comments
Open

Question: using SQL Expression Language table definitions #356

meshantz opened this issue Nov 24, 2020 · 2 comments

Comments

@meshantz
Copy link

Is this a sane pattern to follow to make use of SQLAlchemyAutoSchema with a non-orm (SQL Expression Language) table definition?

from sqlalchemy import Table, Column, Integer, String, MetaData
from sqlalchemy.orm import mapper
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema

meta = MetaData()

example_table = Table('example', meta,
    Column('id', Integer, primary_key=True),
    Column('some_field', String),
)

def make_orm(table):
    class TableRedef:
        pass

    mapped = mapper(TableRedef, table)
    TableRedef.__mapper__ = mapped

    return TableRedef

class ExampleSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = make_orm(example_table)

If there's a better pattern, please let me know. If this is good, I can make a PR to include it in the examples documentation.

@peterschutt
Copy link
Contributor

Hey, I'm not a maintainer but only came across your question today, I know it's a bit of a late response!

There isn't any prose section of the docs that addresses this but in the api reference for SQLAlchemyAutoSchema this example exists:

from marshmallow_sqlalchemy import SQLAlchemyAutoSchema, auto_field

from mymodels import User

class UserSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = User
        # OR
        # table = User.__table__

    created_at = auto_field(dump_only=True)

Notice the commented out part table = User.__table__, which looks to me like you could do this:

class ExampleSchema(SQLAlchemyAutoSchema):
    class Meta:
        table = example_table

...I haven't tested it but if that didn't work it would be a bug IMO.

Support for generating schemas directly from tables comes from here:

def fields_for_table(
self,
table,
*,
include_fk=False,
fields=None,
exclude=None,
base_fields=None,
dict_cls=dict,
):
result = dict_cls()
base_fields = base_fields or {}
for column in table.columns:
key = self._get_field_name(column)
if self._should_exclude_field(column, fields=fields, exclude=exclude):
# Allow marshmallow to validate and exclude the field key.
result[key] = None
continue
if not include_fk and column.foreign_keys:
continue
# Overridden fields are specified relative to key generated by
# self._get_key_for_column(...), rather than keys in source model
field = base_fields.get(key) or self.column2field(column)
if field:
result[key] = field
return result

@meshantz
Copy link
Author

Better late than never! Thanks for the reply.

I'll have to take a look and see if that works. I'll follow up when I get the chance. If it does, it would be nice if it were more prominent in the docs.

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

No branches or pull requests

2 participants