質問編集履歴

1

dj-database-urlのソースコード

2021/08/10 09:09

投稿

Kazuhiro-ch
Kazuhiro-ch

スコア85

test CHANGED
File without changes
test CHANGED
@@ -49,3 +49,321 @@
49
49
  }
50
50
 
51
51
  ```
52
+
53
+
54
+
55
+ 追記
56
+
57
+ ```
58
+
59
+ import os
60
+
61
+
62
+
63
+ try:
64
+
65
+ import urlparse
66
+
67
+ except ImportError:
68
+
69
+ import urllib.parse as urlparse
70
+
71
+
72
+
73
+ try:
74
+
75
+ from django import VERSION as DJANGO_VERSION
76
+
77
+ except ImportError:
78
+
79
+ DJANGO_VERSION = None
80
+
81
+
82
+
83
+
84
+
85
+ # Register database schemes in URLs.
86
+
87
+ urlparse.uses_netloc.append('postgres')
88
+
89
+ urlparse.uses_netloc.append('postgresql')
90
+
91
+ urlparse.uses_netloc.append('pgsql')
92
+
93
+ urlparse.uses_netloc.append('postgis')
94
+
95
+ urlparse.uses_netloc.append('mysql')
96
+
97
+ urlparse.uses_netloc.append('mysql2')
98
+
99
+ urlparse.uses_netloc.append('mysqlgis')
100
+
101
+ urlparse.uses_netloc.append('mysql-connector')
102
+
103
+ urlparse.uses_netloc.append('mssql')
104
+
105
+ urlparse.uses_netloc.append('spatialite')
106
+
107
+ urlparse.uses_netloc.append('sqlite')
108
+
109
+ urlparse.uses_netloc.append('oracle')
110
+
111
+ urlparse.uses_netloc.append('oraclegis')
112
+
113
+ urlparse.uses_netloc.append('redshift')
114
+
115
+
116
+
117
+ DEFAULT_ENV = 'DATABASE_URL'
118
+
119
+
120
+
121
+ SCHEMES = {
122
+
123
+ 'postgis': 'django.contrib.gis.db.backends.postgis',
124
+
125
+ 'mysql': 'django.db.backends.mysql',
126
+
127
+ 'mysql2': 'django.db.backends.mysql',
128
+
129
+ 'mysqlgis': 'django.contrib.gis.db.backends.mysql',
130
+
131
+ 'mysql-connector': 'mysql.connector.django',
132
+
133
+ 'mssql': 'sql_server.pyodbc',
134
+
135
+ 'spatialite': 'django.contrib.gis.db.backends.spatialite',
136
+
137
+ 'sqlite': 'django.db.backends.sqlite3',
138
+
139
+ 'oracle': 'django.db.backends.oracle',
140
+
141
+ 'oraclegis': 'django.contrib.gis.db.backends.oracle',
142
+
143
+ 'redshift': 'django_redshift_backend',
144
+
145
+ }
146
+
147
+
148
+
149
+ # https://docs.djangoproject.com/en/2.0/releases/2.0/#id1
150
+
151
+ if DJANGO_VERSION and DJANGO_VERSION < (2, 0):
152
+
153
+ SCHEMES['postgres'] = 'django.db.backends.postgresql_psycopg2'
154
+
155
+ SCHEMES['postgresql'] = 'django.db.backends.postgresql_psycopg2'
156
+
157
+ SCHEMES['pgsql'] = 'django.db.backends.postgresql_psycopg2'
158
+
159
+ else:
160
+
161
+ SCHEMES['postgres'] = 'django.db.backends.postgresql'
162
+
163
+ SCHEMES['postgresql'] = 'django.db.backends.postgresql'
164
+
165
+ SCHEMES['pgsql'] = 'django.db.backends.postgresql'
166
+
167
+
168
+
169
+
170
+
171
+ def config(env=DEFAULT_ENV, default=None, engine=None, conn_max_age=0, ssl_require=False):
172
+
173
+ """Returns configured DATABASE dictionary from DATABASE_URL."""
174
+
175
+
176
+
177
+ config = {}
178
+
179
+
180
+
181
+ s = os.environ.get(env, default)
182
+
183
+
184
+
185
+ if s:
186
+
187
+ config = parse(s, engine, conn_max_age, ssl_require)
188
+
189
+
190
+
191
+ return config
192
+
193
+
194
+
195
+
196
+
197
+ def parse(url, engine=None, conn_max_age=0, ssl_require=False):
198
+
199
+ """Parses a database URL."""
200
+
201
+
202
+
203
+ if url == 'sqlite://:memory:':
204
+
205
+ # this is a special case, because if we pass this URL into
206
+
207
+ # urlparse, urlparse will choke trying to interpret "memory"
208
+
209
+ # as a port number
210
+
211
+ return {
212
+
213
+ 'ENGINE': SCHEMES['sqlite'],
214
+
215
+ 'NAME': ':memory:'
216
+
217
+ }
218
+
219
+ # note: no other settings are required for sqlite
220
+
221
+
222
+
223
+ # otherwise parse the url as normal
224
+
225
+ config = {}
226
+
227
+
228
+
229
+ url = urlparse.urlparse(url)
230
+
231
+
232
+
233
+ # Split query strings from path.
234
+
235
+ path = url.path[1:]
236
+
237
+ if '?' in path and not url.query:
238
+
239
+ path, query = path.split('?', 2)
240
+
241
+ else:
242
+
243
+ path, query = path, url.query
244
+
245
+ query = urlparse.parse_qs(query)
246
+
247
+
248
+
249
+ # If we are using sqlite and we have no path, then assume we
250
+
251
+ # want an in-memory database (this is the behaviour of sqlalchemy)
252
+
253
+ if url.scheme == 'sqlite' and path == '':
254
+
255
+ path = ':memory:'
256
+
257
+
258
+
259
+ # Handle postgres percent-encoded paths.
260
+
261
+ hostname = url.hostname or ''
262
+
263
+ if '%2f' in hostname.lower():
264
+
265
+ # Switch to url.netloc to avoid lower cased paths
266
+
267
+ hostname = url.netloc
268
+
269
+ if "@" in hostname:
270
+
271
+ hostname = hostname.rsplit("@", 1)[1]
272
+
273
+ if ":" in hostname:
274
+
275
+ hostname = hostname.split(":", 1)[0]
276
+
277
+ hostname = hostname.replace('%2f', '/').replace('%2F', '/')
278
+
279
+
280
+
281
+ # Lookup specified engine.
282
+
283
+ engine = SCHEMES[url.scheme] if engine is None else engine
284
+
285
+
286
+
287
+ port = (str(url.port) if url.port and engine in [SCHEMES['oracle'], SCHEMES['mssql']]
288
+
289
+ else url.port)
290
+
291
+
292
+
293
+ # Update with environment configuration.
294
+
295
+ config.update({
296
+
297
+ 'NAME': urlparse.unquote(path or ''),
298
+
299
+ 'USER': urlparse.unquote(url.username or ''),
300
+
301
+ 'PASSWORD': urlparse.unquote(url.password or ''),
302
+
303
+ 'HOST': hostname,
304
+
305
+ 'PORT': port or '',
306
+
307
+ 'CONN_MAX_AGE': conn_max_age,
308
+
309
+ })
310
+
311
+
312
+
313
+ # Pass the query string into OPTIONS.
314
+
315
+ options = {}
316
+
317
+ for key, values in query.items():
318
+
319
+ if url.scheme == 'mysql' and key == 'ssl-ca':
320
+
321
+ options['ssl'] = {'ca': values[-1]}
322
+
323
+ continue
324
+
325
+
326
+
327
+ options[key] = values[-1]
328
+
329
+
330
+
331
+ if ssl_require:
332
+
333
+ options['sslmode'] = 'require'
334
+
335
+
336
+
337
+ # Support for Postgres Schema URLs
338
+
339
+ if 'currentSchema' in options and engine in (
340
+
341
+ 'django.contrib.gis.db.backends.postgis',
342
+
343
+ 'django.db.backends.postgresql_psycopg2',
344
+
345
+ 'django.db.backends.postgresql',
346
+
347
+ 'django_redshift_backend',
348
+
349
+ ):
350
+
351
+ options['options'] = '-c search_path={0}'.format(options.pop('currentSchema'))
352
+
353
+
354
+
355
+ if options:
356
+
357
+ config['OPTIONS'] = options
358
+
359
+
360
+
361
+ if engine:
362
+
363
+ config['ENGINE'] = engine
364
+
365
+
366
+
367
+ return config
368
+
369
+ ```