55from urllib .parse import urlparse
66
77import pandas as pd
8- from django .http import HttpRequest , HttpResponseRedirect , JsonResponse
8+ from django .core .serializers import serialize
9+ from django .http import HttpRequest , HttpResponse , HttpResponseRedirect , JsonResponse
910from django .views import View
1011
1112from datetime import timedelta
1213
1314from django .db .models import Sum
1415from django .utils import timezone
1516
16- from backend .apps .api .v1 .models import BigQueryType , CloudTable , Column , Dataset , Table
17+ from backend .apps .api .v1 .models import (
18+ BigQueryType ,
19+ CloudTable ,
20+ Column ,
21+ get_temporal_coverage ,
22+ Dataset ,
23+ Table ,
24+ )
1725
1826URL_MAPPING = {
1927 "localhost:8080" : "http://localhost:3000" ,
@@ -160,4 +168,101 @@ def table_stats(request: HttpRequest):
160168 "total_rows" : aggregates ["total_rows" ] or 0 ,
161169 }
162170
163- return JsonResponse (data )
171+ return JsonResponse (data )
172+
173+ def columns_view (request : HttpRequest , table_id : str = None , column_id : str = None ):
174+ """
175+ A simple REST API view for Columns.
176+ """
177+ if column_id :
178+ try :
179+ column = Column .objects .select_related (
180+ "table" , "table__dataset" , "bigquery_type"
181+ ).get (id = column_id )
182+ data = serialize (
183+ "json" ,
184+ [column ],
185+ fields = (
186+ "name" ,
187+ "description" ,
188+ "bigquery_type" ,
189+ "is_primary_key" ,
190+ "table" ,
191+ ),
192+ )
193+ return HttpResponse (data , content_type = "application/json" )
194+ except Column .DoesNotExist :
195+ return JsonResponse ({"error" : "Column not found" }, status = 404 )
196+ elif table_id :
197+ columns = (
198+ Column .objects .filter (table_id = table_id )
199+ .select_related (
200+ "table" ,
201+ "table__dataset" ,
202+ "bigquery_type" ,
203+ "directory_primary_key__table__dataset" ,
204+ )
205+ .prefetch_related (
206+ "directory_primary_key__table__cloud_tables" ,
207+ "coverages__datetime_ranges"
208+ )
209+ .order_by ("order" )
210+ )
211+
212+ if not columns .exists ():
213+ return JsonResponse ({"error" : "Table not found or has no columns" }, status = 404 )
214+
215+ results = []
216+ table_temporal_coverage = None
217+ for col in columns :
218+ col_data = {
219+ "id" : str (col .id ),
220+ "order" : col .order ,
221+ "name" : col .name ,
222+ "description" : col .description ,
223+ "bigquery_type" : {"name" : col .bigquery_type .name if col .bigquery_type else None },
224+ "is_primary_key" : col .is_primary_key ,
225+ "covered_by_dictionary" : col .covered_by_dictionary ,
226+ "measurement_unit" : col .measurement_unit ,
227+ "contains_sensitive_data" : col .contains_sensitive_data ,
228+ "observations" : col .observations ,
229+ "temporal_coverage" : None ,
230+ "directory_primary_key" : None ,
231+ }
232+
233+ col_coverage = get_temporal_coverage ([col ])
234+ if not col_coverage .get ("start" ) and not col_coverage .get ("end" ):
235+ if table_temporal_coverage is None :
236+ table_temporal_coverage = col .table .temporal_coverage_from_table
237+ col_data ["temporal_coverage" ] = table_temporal_coverage
238+ else :
239+ col_data ["temporal_coverage" ] = col_coverage
240+
241+ if dpk := col .directory_primary_key :
242+ cloud_table = dpk .table .cloud_tables .first ()
243+ col_data ["directory_primary_key" ] = {
244+ "id" : str (dpk .id ),
245+ "name" : dpk .name ,
246+ "table" : {
247+ "id" : str (dpk .table .id ),
248+ "name" : dpk .table .name ,
249+ "is_closed" : dpk .table .is_closed ,
250+ "uncompressed_file_size" : dpk .table .uncompressed_file_size ,
251+ "dataset" : {
252+ "id" : str (dpk .table .dataset .id ),
253+ "name" : dpk .table .dataset .name ,
254+ },
255+ "cloud_table" : {"gcp_table_id" : cloud_table .gcp_table_id , "gcp_dataset_id" : cloud_table .gcp_dataset_id , "gcp_project_id" : cloud_table .gcp_project_id } if cloud_table else None
256+ },
257+ }
258+ results .append (col_data )
259+
260+ return JsonResponse (results , safe = False )
261+ else :
262+ columns = Column .objects .all ()[:100 ]
263+ data = serialize (
264+ "json" ,
265+ columns ,
266+ fields = ("id" , "name" , "table" ),
267+ )
268+ return HttpResponse (data , content_type = "application/json" )
0 commit comments