Skip to content

Conversation

@mehdigmira
Copy link
Contributor

@mehdigmira mehdigmira commented Feb 9, 2019

  • The JSON type can also be a list, and is not restricted to a dict.
  • Added the enums attribute to Enum class

Copy link
Contributor

@ilevkivskyi ilevkivskyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for PR! I have couple comments.

def result_processor(self, dialect: Dialect, coltype: Any) -> Callable[[Optional[str]], Optional[timedelta]]: ...

class JSON(Indexable, TypeEngine[Dict[str, Any]]):
_JSONT = Union[Dict[str, Any], List[Any]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this cause some problems in actual code? If this is made from the point of view of general correctness, then I wouldn't do this.

Even if it caused some problems, I think this will likely cause lots of false positives, reading this attribute from a model will need to be always followed by an isinstance(..., dict).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have multiple JSON fields that look like [{"from": 1, "to": "3", "name": "x"}, ...]. So in our case it created a lot of false negatives.
In PostgreSQL (and hence SQLAlchemy) there as many operators to handle [{"from": 1, "to": "3", "name": "x"}, ...] as there are for {"from": 1, "to": "3", "name": "x"}. So I thinks It's a very common practice to have lists. https://www.postgresql.org/docs/9.3/functions-json.html

Maybe a solution would be to give a hint when creating the column ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for a delay, coming back to this.

So in our case it created a lot of false negatives.

I would say that false negatives are less important that false positives, the other changes in this PR are OK however.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I meant false positives. Again, a JSON field is not a dict. It is very common to store smth like [{"from": 1, "to": "3", "name": "x"}, ...]. It is both supported by Postgres and SQLAlchemy.
This causes any code such as MyModel.my_json_col[0] to be marked as an error. Adding a type ignore to every occurence is not an option IMO.
What is the rational behind setting JSONB to be a dict ?

def bind_processor(self, dialect: Dialect) -> Callable[[Optional[Dict[str, Any]]], Optional[str]]: ...
def result_processor(self, dialect: Dialect, coltype: Any) -> Callable[[Optional[str]], Optional[Dict[str, Any]]]: ...
def bind_processor(self, dialect: Dialect) -> Callable[[Optional[_JSONT]], Optional[str]]: ...
def result_processor(self, dialect: Dialect, coltype: Any) -> Callable[[Optional[str]], Optional[_JSONT]]: ...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning more precise types here are probably fine however.

@ilevkivskyi
Copy link
Contributor

I finally had time time to check this against our internal code bases and it looks like this is clean, so can be merged now. Sorry for a delay.

@ilevkivskyi ilevkivskyi merged commit 638b850 into dropbox:master Jul 10, 2019
@ckarnell
Copy link
Contributor

I just want to comment in case anyone else is upgrading and is seeing this as a pretty big breaking change for them, resulting in many errors that look like this: "error: No overload variant of "getitem" of "list" matches argument type "str" [call-overload]".

An easy fix is to do the following for JSON columns that semantically can only ever be a Dict[str, Any], for example:

from typing import cast, Any, Dict, Optional

json_column = cast('Column[Optional[Dict[str, Any]]]', Column(JSONB))

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

Successfully merging this pull request may close these issues.

3 participants