stefanofontanelli / ColanderAlchemy

ColanderAlchemy helps you autogenerating Colander schemas based on SQLAlchemy mapped objects.
Other
65 stars 32 forks source link

Make SQLAlchemySchemaNode truly subclassable #66

Open ztane opened 9 years ago

ztane commented 9 years ago

The documentation claims the following:

If the available customisation isn’t sufficient, then you can subclass the following colanderalchemy.SQLAlchemySchemaNode methods when you need more control:

SQLAlchemySchemaNode.get_schema_from_column(), which returns a colander.SchemaNode given a sqlachemy.schema.Column SQLAlchemySchemaNode.get_schema_from_relationship(), which returns a colander.SchemaNode given a sqlalchemy.orm.relationship."

Now, I wanted to add new types to get_schema_from_column (we are using postgresql JSON and TEXT[] and didn't want ColanderAlchemy to crash on these. If we need to add these, we need to copy paste the entire get_schema_from_column definition and add lines there. Furthermore, since SQLAlchemySchemaNode itself is hardcoded in the get_schema_from_relationship, the subobjects cannot use our subclass, so we need to fork get_schema_from_relationship too. All in all, easier just to fork the entire codebase.

Now, the solution could be to break the get_schema_from_column into parts that have overrideable methods - for example consult a method instead of throwing a NotImplementedError, and use an overrideable method to create new SQLAlchemySchemaNodes for relationships, etc.

tisdall commented 9 years ago

All good points. Would you like to provide a pull request that implements some of these suggestions? I'm fine with you just extending the code to accommodate those additional types.

At the very least, we should probably eliminate that claim in the docs.

uralbash commented 9 years ago

Maybe this PR #69 will solve your problem. You can override the standart strategy form generation, using their own field. I'm trying to do now in sacrud_deform.

tisdall commented 9 years ago

glancing over this again... Isn't this solved with using the "info" value on the column to define a typ? Something like:

json = Column(JSON,
              info={'colanderalchemy': {
                  'typ': colander.Text(),
              }})