This repository was archived by the owner on May 19, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathquery_examples.py
More file actions
290 lines (257 loc) · 10.6 KB
/
Copy pathquery_examples.py
File metadata and controls
290 lines (257 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
import psycopg2
import os
from datetime import datetime
import pandas as pd
from tabulate import tabulate # Import the function directly
# Connection parameters
db_params = {
"dbname": "gisdb",
"user": "admin",
"password": "admin",
"host": "localhost",
"port": 5432
}
def run_query(conn, query, description, save_results=True, limit_display=10):
"""Run a query and display/save results"""
cursor = conn.cursor()
print(f"\n=== {description} ===")
print(f"SQL: {query}")
try:
cursor.execute(query)
results = cursor.fetchall()
column_names = [desc[0] for desc in cursor.description]
# Create DataFrame
df = pd.DataFrame(results, columns=column_names)
# Display results
if len(df) > 0:
print(f"\nResults ({len(df)} rows, showing first {min(limit_display, len(df))}):")
print(tabulate(df.head(limit_display), headers='keys', tablefmt='psql', showindex=False))
else:
print("No results returned.")
# Save results if requested
if save_results and len(df) > 0:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
# Create a safe filename
safe_desc = "".join(c if c.isalnum() else "_" for c in description)
filename = f"results_{safe_desc}_{timestamp}.csv"
df.to_csv(filename, index=False)
print(f"Results saved to: {filename}")
return df
except Exception as e:
print(f"Error executing query: {e}")
return None
finally:
cursor.close()
def run_power_plant_queries(table_name="power_plants"):
"""Run a series of example queries on the power plants data"""
try:
conn = psycopg2.connect(**db_params)
# First, let's check the actual column names to avoid errors
column_query = f"""
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = '{table_name}'
ORDER BY ordinal_position;
"""
columns_df = run_query(conn, column_query, "Table Columns", save_results=True)
if columns_df is None or len(columns_df) == 0:
print(f"Error: Could not retrieve columns for table '{table_name}'")
return
# Get the actual column names from the database to use in our queries
column_names = columns_df['column_name'].tolist()
# Find capacity-related column (might be named differently)
capacity_col = None
for col in column_names:
if 'capacity' in col.lower() or 'mw' in col.lower():
capacity_col = col
print(f"Found capacity column: {capacity_col}")
break
# Find name-related column
name_col = None
for col in column_names:
if col.lower() in ['name', 'plant_name', 'station_name']:
name_col = col
print(f"Found name column: {name_col}")
break
# Find type-related column
type_col = None
for col in column_names:
if col.lower() in ['type', 'plant_type', 'station_type']:
type_col = col
print(f"Found type column: {type_col}")
break
# Basic queries
basic_query = f"""
SELECT * FROM {table_name}
LIMIT 10;
"""
run_query(conn, basic_query, "Basic Sample of Data")
# Only run the type-based query if we found a type column
if type_col:
count_by_type_query = f"""
SELECT "{type_col}", COUNT(*) as count
FROM {table_name}
GROUP BY "{type_col}"
ORDER BY count DESC;
"""
run_query(conn, count_by_type_query, "Power Plants by Type")
# Only run the capacity query if we found name, type, and capacity columns
if name_col and type_col and capacity_col:
capacity_query = f"""
SELECT "{name_col}", "{type_col}", "{capacity_col}" as capacity
FROM {table_name}
WHERE "{capacity_col}" IS NOT NULL
ORDER BY "{capacity_col}" DESC
LIMIT 20;
"""
run_query(conn, capacity_query, "Largest Capacity Power Plants")
# Spatial query - find plants within a radius of a point
# Example: Plants within 100km of Chicago
chicago_query = f"""
SELECT
{', '.join([f'"{col}"' for col in column_names if col != 'geom'])},
ST_Distance(
geom,
ST_SetSRID(ST_MakePoint(-87.6298, 41.8781), 4326)::geography
)/1000 as distance_km
FROM {table_name}
WHERE ST_DWithin(
geom,
ST_SetSRID(ST_MakePoint(-87.6298, 41.8781), 4326)::geography,
100000 -- 100km in meters
)
ORDER BY distance_km
LIMIT 100;
"""
run_query(conn, chicago_query, "Power Plants within 100km of Chicago")
# Check if states table exists before running the query
check_states = """
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_name = 'states'
);
"""
states_check = run_query(conn, check_states, "Check if states table exists", save_results=False)
if states_check is not None and states_check.iloc[0, 0]:
# Spatial aggregation - count plants by state using spatial join
state_query = f"""
SELECT states.name as state_name, COUNT(*) as plant_count
FROM {table_name} plants
JOIN states ON ST_Contains(states.geom, plants.geom)
GROUP BY states.name
ORDER BY plant_count DESC;
"""
run_query(conn, state_query, "Power Plants Count by State")
else:
print("\n=== Power Plants Count by State ===")
print("Skipped - 'states' table doesn't exist.")
print("To run this query, you would need to import state boundaries.")
# Simple data aggregation - counts by bounding box quadrants
quadrants_query = f"""
WITH bounds AS (
SELECT
ST_XMin(ST_Extent(geom)) as min_lon,
ST_XMax(ST_Extent(geom)) as max_lon,
ST_YMin(ST_Extent(geom)) as min_lat,
ST_YMax(ST_Extent(geom)) as max_lat
FROM {table_name}
),
quadrants AS (
SELECT
CASE
WHEN ST_X(geom) < (SELECT (min_lon + max_lon)/2 FROM bounds) THEN 'West'
ELSE 'East'
END as longitude_half,
CASE
WHEN ST_Y(geom) < (SELECT (min_lat + max_lat)/2 FROM bounds) THEN 'South'
ELSE 'North'
END as latitude_half
FROM {table_name}
)
SELECT
longitude_half || ' ' || latitude_half as quadrant,
COUNT(*) as plant_count
FROM quadrants
GROUP BY quadrant
ORDER BY plant_count DESC;
"""
run_query(conn, quadrants_query, "Power Plants by Geographic Quadrant")
# Distance analysis - nearest neighbors
if name_col and type_col:
# Find plants with 'nuclear' in their type
nuclear_check = f"""
SELECT COUNT(*)
FROM {table_name}
WHERE "{type_col}" ILIKE '%nuclear%';
"""
nuclear_result = run_query(conn, nuclear_check, "Check for nuclear plants", save_results=False)
if nuclear_result is not None and nuclear_result.iloc[0, 0] > 0:
nearest_query = f"""
WITH nuclear_plants AS (
SELECT id, "{name_col}", geom
FROM {table_name}
WHERE "{type_col}" ILIKE '%nuclear%'
LIMIT 20 -- For performance
)
SELECT
np."{name_col}" as nuclear_plant,
p."{name_col}" as nearest_plant,
p."{type_col}" as plant_type,
ST_Distance(np.geom, p.geom::geography)/1000 as distance_km
FROM nuclear_plants np
CROSS JOIN LATERAL (
SELECT "{name_col}", "{type_col}", geom
FROM {table_name}
WHERE "{type_col}" NOT ILIKE '%nuclear%'
ORDER BY np.geom <-> geom
LIMIT 1
) p
ORDER BY distance_km
LIMIT 20;
"""
run_query(conn, nearest_query, "Nearest Non-Nuclear Plant to Each Nuclear Plant")
# GeoJSON Export for mapping visualization
if name_col:
cols_to_include = [col for col in [name_col, type_col, capacity_col] if col is not None]
properties_json = ", ".join([f"'{col}', \"{col}\"" for col in cols_to_include])
geojson_query = f"""
SELECT json_build_object(
'type', 'FeatureCollection',
'features', json_agg(
json_build_object(
'type', 'Feature',
'geometry', ST_AsGeoJSON(geom)::json,
'properties', json_build_object(
'id', id,
{properties_json}
)
)
)
) as geojson
FROM (
SELECT id, {', '.join([f'"{col}"' for col in cols_to_include])}, geom
FROM {table_name}
LIMIT 100 -- Limit for performance
) sub;
"""
run_query(conn, geojson_query, "GeoJSON Export Sample", limit_display=1)
print("\n\nAll queries completed. Results have been saved to CSV files.")
except Exception as e:
print(f"Error: {e}")
finally:
if 'conn' in locals():
conn.close()
if __name__ == "__main__":
# Install required packages if needed
try:
import pandas as pd
from tabulate import tabulate # Corrected import
except ImportError:
print("Installing required packages...")
os.system("pip install pandas tabulate")
import pandas as pd
from tabulate import tabulate
table_name = input("Enter the power plants table name (default: power_plants): ")
if not table_name:
table_name = "power_plants"
run_power_plant_queries(table_name)