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

Unexpected differing behavior for db.String and db.Text on Postgres (latter saves empty field as "") #1840

Closed
boydgreenfield opened this issue Apr 4, 2019 · 1 comment · Fixed by #2321

Comments

@boydgreenfield
Copy link

boydgreenfield commented Apr 4, 2019

This seems related to a bunch of closed issues around handling nullable and non-nullable fields, but I recently was stumped by the following (IMO) weird behavior:

from app import admin, db  # vanilla Flask setup
from flask_admin.contrib.sqla import ModelView

# Declarative model using Flask-SQLAlchemy, Postgres as the backend
class Document(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String)

class Document2(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.Text)

### Add to Flask-Admin instance
admin.add_view(ModelView(Document, db.session))

Leads to Document instances having a null description field when they're created in Flask-Admin (what I'd expect by default) and Document2 instances having an empty string. In Postgres, I believe these are actually equivalent, so I can just use db.String as a workaround.

Is this a bug? Edge case of something about these column types I'm not thinking of (or that doesn;'t apply to Postgres)? Certainly a bit of a gotcha that I didn't jump out at me in any of the documentation or examples.

@b-ryan
Copy link

b-ryan commented Jun 17, 2019

I ran into this as well. I tracked it down to the difference between these two functions:

https://github.com/flask-admin/flask-admin/blob/d29796b6998b9fc86fbf0acc08aba0b27edbd013/flask_admin/contrib/sqla/form.py#L274-L301

The text converter doesn't do any work to check if the column is nullable and this is, I believe, the root of the issue.

I came up with the following to get around this

class MyModelConverter(sqla.form.AdminModelConverter):

    real_text_columns = [
        # any columns that should be treated like textarea fields should be listed here
    ]

    @converts("Text")
    def conv_Text(self, field_args, **extra):
        if extra["column"] in self.real_text_columns:
            return super().conv_Text(field_args, **extra)
        column = extra.pop("column")
        return self.conv_String(column, field_args, **extra)

There's certainly issues with this, like that you have to explicitly list out the "real" text columns. And I don't know what the implications of @converts("Text") are. However, it's working for my own purposes.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants