27
27
class ORMField (OrderedType ):
28
28
def __init__ (
29
29
self ,
30
- prop_name = None ,
30
+ model_attr = None ,
31
31
type = None ,
32
32
required = None ,
33
33
description = None ,
@@ -55,27 +55,26 @@ class Meta:
55
55
-> MyType.id will be of type Int (vs ID).
56
56
-> MyType.name will be of type NonNull(String) (vs String).
57
57
58
- Parameters
59
- - prop_name : str, optional
60
- Name of the SQLAlchemy property used to resolve this field.
58
+ :param str model_attr:
59
+ Name of the SQLAlchemy model attribute used to resolve this field.
61
60
Default to the name of the attribute referencing the ORMField.
62
- - type: optional
61
+ :param type:
63
62
Default to the type mapping in converter.py.
64
- - description: str, optional
63
+ :param str description:
65
64
Default to the `doc` attribute of the SQLAlchemy column property.
66
- - required: bool, optional
65
+ :param bool required:
67
66
Default to the opposite of the `nullable` attribute of the SQLAlchemy column property.
68
- - description: str, optional
67
+ :param str description:
69
68
Same behavior as in graphene.Field. Defaults to None.
70
- - deprecation_reason: str, optional
69
+ :param str deprecation_reason:
71
70
Same behavior as in graphene.Field. Defaults to None.
72
- - _creation_counter: int, optional
71
+ :param int _creation_counter:
73
72
Same behavior as in graphene.Field.
74
73
"""
75
74
super (ORMField , self ).__init__ (_creation_counter = _creation_counter )
76
75
# The is only useful for documentation and auto-completion
77
76
common_kwargs = {
78
- 'prop_name ' : prop_name ,
77
+ 'model_attr ' : model_attr ,
79
78
'type' : type ,
80
79
'required' : required ,
81
80
'description' : description ,
@@ -92,25 +91,21 @@ def construct_fields(
92
91
"""
93
92
Construct all the fields for a SQLAlchemyObjectType.
94
93
The main steps are:
95
- - Gather all the relevant attributes from the SQLAlchemy model
96
- - Gather all the ORM fields defined on the type
97
- - Merge in overrides and build up all the fields
98
-
99
- Parameters
100
- - obj_type : SQLAlchemyObjectType
101
- - model : the SQLAlchemy model
102
- - registry : Registry
103
- - only_fields : tuple[string]
104
- - exclude_fields : tuple[string]
105
- - connection_field_factory : function
106
-
107
- Returns
108
- - fields
109
- An OrderedDict of field names to graphene.Field
94
+ - Gather all the relevant attributes from the SQLAlchemy model
95
+ - Gather all the ORM fields defined on the type
96
+ - Merge in overrides and build up all the fields
97
+
98
+ :param SQLAlchemyObjectType obj_type:
99
+ :param model: the SQLAlchemy model
100
+ :param Registry registry:
101
+ :param tuple[string] only_fields:
102
+ :param tuple[string] exclude_fields:
103
+ :param function connection_field_factory:
104
+ :rtype: OrderedDict[str, graphene.Field]
110
105
"""
111
106
inspected_model = sqlalchemyinspect (model )
112
- # Gather all the relevant attributes from the SQLAlchemy model
113
- all_model_props = OrderedDict (
107
+ # Gather all the relevant attributes from the SQLAlchemy model in order
108
+ all_model_attrs = OrderedDict (
114
109
inspected_model .column_attrs .items () +
115
110
inspected_model .composites .items () +
116
111
[(name , item ) for name , item in inspected_model .all_orm_descriptors .items ()
@@ -120,57 +115,57 @@ def construct_fields(
120
115
121
116
# Filter out excluded fields
122
117
auto_orm_field_names = []
123
- for prop_name , prop in all_model_props .items ():
124
- if (only_fields and prop_name not in only_fields ) or (prop_name in exclude_fields ):
118
+ for attr_name , attr in all_model_attrs .items ():
119
+ if (only_fields and attr_name not in only_fields ) or (attr_name in exclude_fields ):
125
120
continue
126
- auto_orm_field_names .append (prop_name )
121
+ auto_orm_field_names .append (attr_name )
127
122
128
123
# Gather all the ORM fields defined on the type
129
124
custom_orm_fields_items = [
130
- (attname , value )
125
+ (attn_name , attr )
131
126
for base in reversed (obj_type .__mro__ )
132
- for attname , value in base .__dict__ .items ()
133
- if isinstance (value , ORMField )
127
+ for attn_name , attr in base .__dict__ .items ()
128
+ if isinstance (attr , ORMField )
134
129
]
135
130
custom_orm_fields_items = sorted (custom_orm_fields_items , key = lambda item : item [1 ])
136
131
137
- # Set the prop_name if not set
132
+ # Set the model_attr if not set
138
133
for orm_field_name , orm_field in custom_orm_fields_items :
139
- prop_name = orm_field .kwargs .get ('prop_name ' , orm_field_name )
140
- if prop_name not in all_model_props :
134
+ attr_name = orm_field .kwargs .get ('model_attr ' , orm_field_name )
135
+ if attr_name not in all_model_attrs :
141
136
raise Exception ('Cannot map ORMField "{}" to SQLAlchemy model property' .format (orm_field_name ))
142
- orm_field .kwargs ['prop_name ' ] = prop_name
137
+ orm_field .kwargs ['model_attr ' ] = attr_name
143
138
144
139
# Merge automatic fields with custom ORM fields
145
140
orm_fields = OrderedDict (custom_orm_fields_items )
146
141
for orm_field_name in auto_orm_field_names :
147
142
if orm_field_name in orm_fields :
148
143
continue
149
- orm_fields [orm_field_name ] = ORMField (prop_name = orm_field_name )
144
+ orm_fields [orm_field_name ] = ORMField (model_attr = orm_field_name )
150
145
151
146
# Build all the field dictionary
152
147
fields = OrderedDict ()
153
148
for orm_field_name , orm_field in orm_fields .items ():
154
- prop_name = orm_field .kwargs .pop ('prop_name ' )
155
- prop = all_model_props [ prop_name ]
156
-
157
- if isinstance (prop , ColumnProperty ):
158
- field = convert_sqlalchemy_column (prop , registry , ** orm_field .kwargs )
159
- elif isinstance (prop , RelationshipProperty ):
160
- field = convert_sqlalchemy_relationship (prop , registry , connection_field_factory , ** orm_field .kwargs )
161
- elif isinstance (prop , CompositeProperty ):
162
- if prop_name != orm_field_name or orm_field .kwargs :
149
+ attr_name = orm_field .kwargs .pop ('model_attr ' )
150
+ attr = all_model_attrs [ attr_name ]
151
+
152
+ if isinstance (attr , ColumnProperty ):
153
+ field = convert_sqlalchemy_column (attr , registry , ** orm_field .kwargs )
154
+ elif isinstance (attr , RelationshipProperty ):
155
+ field = convert_sqlalchemy_relationship (attr , registry , connection_field_factory , ** orm_field .kwargs )
156
+ elif isinstance (attr , CompositeProperty ):
157
+ if attr_name != orm_field_name or orm_field .kwargs :
163
158
# TODO Add a way to override composite property fields
164
159
raise ValueError (
165
160
"ORMField kwargs for composite fields must be empty. "
166
161
"Field: {}.{}" .format (obj_type .__name__ , orm_field_name ))
167
- field = convert_sqlalchemy_composite (prop , registry )
168
- elif isinstance (prop , hybrid_property ):
169
- field = convert_sqlalchemy_hybrid_method (prop , prop_name , ** orm_field .kwargs )
162
+ field = convert_sqlalchemy_composite (attr , registry )
163
+ elif isinstance (attr , hybrid_property ):
164
+ field = convert_sqlalchemy_hybrid_method (attr , attr_name , ** orm_field .kwargs )
170
165
else :
171
166
raise Exception ('Property type is not supported' ) # Should never happen
172
167
173
- registry .register_orm_field (obj_type , orm_field_name , prop )
168
+ registry .register_orm_field (obj_type , orm_field_name , attr )
174
169
fields [orm_field_name ] = field
175
170
176
171
return fields
0 commit comments