@@ -1268,8 +1268,9 @@ def arrow(self, key: str) -> JSONB:
12681268 Allows part of the JSON structure to be returned - for example,
12691269 for {"a": 1}, and a key value of "a", then 1 will be returned.
12701270 """
1271- self .json_operator = f"-> '{ key } '"
1272- return self
1271+ instance = t .cast (JSONB , self .copy ())
1272+ instance .json_operator = f"-> '{ key } '"
1273+ return instance
12731274
12741275 def get_select_string (self , engine_type : str , just_alias = False ) -> str :
12751276 select_string = self ._meta .get_full_name (just_alias = just_alias )
@@ -1383,6 +1384,7 @@ def __init__(
13831384
13841385 self .base_column = base_column
13851386 self .default = default
1387+ self .index : t .Optional [int ] = None
13861388 kwargs .update ({"base_column" : base_column , "default" : default })
13871389 super ().__init__ (** kwargs )
13881390
@@ -1394,3 +1396,41 @@ def column_type(self):
13941396 elif engine_type == "sqlite" :
13951397 return "ARRAY"
13961398 raise Exception ("Unrecognized engine type" )
1399+
1400+ def __getitem__ (self , value : int ) -> Array :
1401+ """
1402+ Allows queries which retrieve an item from the array. The index starts
1403+ with 0 for the first value. If you were to write the SQL by hand, the
1404+ first index would be 1 instead:
1405+
1406+ https://www.postgresql.org/docs/current/arrays.html
1407+
1408+ However, we keep the first index as 0 to fit better with Python.
1409+
1410+ For example:
1411+
1412+ .. code-block:: python
1413+
1414+ Ticket.select(Ticket.seat_numbers[1]).run_sync
1415+
1416+ """
1417+ if isinstance (value , int ):
1418+ if value < 0 :
1419+ raise ValueError ("Only positive integers are allowed." )
1420+
1421+ instance = t .cast (Array , self .copy ())
1422+
1423+ # We deliberately add 1, as Postgres treats the first array element
1424+ # as index 1.
1425+ instance .index = value + 1
1426+ return instance
1427+ else :
1428+ raise ValueError ("Only integers can be used for indexing." )
1429+
1430+ def get_select_string (self , engine_type : str , just_alias = False ) -> str :
1431+ select_string = self ._meta .get_full_name (just_alias = just_alias )
1432+
1433+ if isinstance (self .index , int ):
1434+ return f"{ select_string } [{ self .index } ]"
1435+ else :
1436+ return select_string
0 commit comments