pgbelt 0.6.2__py3-none-any.whl → 0.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pgbelt/cmd/convenience.py CHANGED
@@ -34,9 +34,7 @@ def src_dsn(
34
34
  echo(
35
35
  conf.src.owner_dsn
36
36
  if owner
37
- else conf.src.pglogical_dsn
38
- if pglogical
39
- else conf.src.root_dsn
37
+ else conf.src.pglogical_dsn if pglogical else conf.src.root_dsn
40
38
  )
41
39
 
42
40
 
@@ -56,9 +54,7 @@ def dst_dsn(
56
54
  echo(
57
55
  conf.dst.owner_dsn
58
56
  if owner
59
- else conf.dst.pglogical_dsn
60
- if pglogical
61
- else conf.dst.root_dsn
57
+ else conf.dst.pglogical_dsn if pglogical else conf.dst.root_dsn
62
58
  )
63
59
 
64
60
 
@@ -66,7 +62,9 @@ async def _check_pkeys(
66
62
  conf: DbupgradeConfig, logger: Logger
67
63
  ) -> tuple[list[str], list[str]]:
68
64
  async with create_pool(conf.src.root_uri, min_size=1) as pool:
69
- pkey_tables, no_pkey_tables, _ = await analyze_table_pkeys(pool, logger)
65
+ pkey_tables, no_pkey_tables, _ = await analyze_table_pkeys(
66
+ pool, conf.schema_name, logger
67
+ )
70
68
  return pkey_tables, no_pkey_tables
71
69
 
72
70
 
pgbelt/cmd/preflight.py CHANGED
@@ -12,7 +12,46 @@ from typer import echo
12
12
  from typer import style
13
13
 
14
14
 
15
- async def _print_prechecks(results: list[dict]) -> list[list]:
15
+ def _summary_table(results: dict, compared_extensions: list[str] = None) -> list[list]:
16
+ """
17
+ Takes a dict of precheck results for all databases and returns a summary table for echo.
18
+
19
+ The summary table alters slightly if the results are for a destination database.
20
+
21
+ results format:
22
+ [
23
+ {
24
+ "server_version": "9.6.20",
25
+ "max_replication_slots": "10",
26
+ "max_worker_processes": "10",
27
+ "max_wal_senders": "10",
28
+ "shared_preload_libraries": ["pg_stat_statements", ...],
29
+ "rds.logical_replication": "on",
30
+ "schema: "public",
31
+ "extensions": ["uuid-ossp", ...],
32
+ "users": { // See pgbelt.util.postgres.precheck_info results["users"] for more info.
33
+ "root": {
34
+ "rolname": "root",
35
+ "rolcanlogin": True,
36
+ "rolcreaterole": True,
37
+ "rolinherit": True,
38
+ "rolsuper": True,
39
+ "memberof": ["rds_superuser", ...]
40
+ },
41
+ "owner": {
42
+ "rolname": "owner",
43
+ "rolcanlogin": True,
44
+ "rolcreaterole": False,
45
+ "rolinherit": True,
46
+ "rolsuper": False,
47
+ "memberof": ["rds_superuser", ...]
48
+ }
49
+ }
50
+ },
51
+ ...
52
+ ]
53
+ """
54
+
16
55
  summary_table = [
17
56
  [
18
57
  style("database", "yellow"),
@@ -20,11 +59,12 @@ async def _print_prechecks(results: list[dict]) -> list[list]:
20
59
  style("max_replication_slots", "yellow"),
21
60
  style("max_worker_processes", "yellow"),
22
61
  style("max_wal_senders", "yellow"),
23
- style("pg_stat_statements", "yellow"),
24
- style("pglogical", "yellow"),
62
+ style("shared_preload_libraries", "yellow"),
25
63
  style("rds.logical_replication", "yellow"),
26
64
  style("root user ok", "yellow"),
27
65
  style("owner user ok", "yellow"),
66
+ style("targeted schema", "yellow"),
67
+ style("extensions ok", "yellow"),
28
68
  ]
29
69
  ]
30
70
 
@@ -32,30 +72,49 @@ async def _print_prechecks(results: list[dict]) -> list[list]:
32
72
 
33
73
  for r in results:
34
74
  root_ok = (
35
- r["root"]["rolcanlogin"]
36
- and r["root"]["rolcreaterole"]
37
- and r["root"]["rolinherit"]
38
- ) and ("rds_superuser" in r["root"]["memberof"] or r["root"]["rolsuper"])
39
- owner_ok = r["owner"]["rolcanlogin"]
40
- pg_stat_statements = (
41
- "installed"
42
- if "pg_stat_statements" in r["shared_preload_libraries"]
43
- else "not installed"
44
- )
45
- pglogical = (
46
- "installed"
47
- if "pglogical" in r["shared_preload_libraries"]
48
- else "not installed"
75
+ r["users"]["root"]["rolcanlogin"]
76
+ and r["users"]["root"]["rolcreaterole"]
77
+ and r["users"]["root"]["rolinherit"]
78
+ ) and (
79
+ "rds_superuser" in r["users"]["root"]["memberof"]
80
+ or r["users"]["root"]["rolsuper"]
49
81
  )
82
+
83
+ # Interestingly enough, we can tell if this is being run for a destination database if the compared_extensions is not None.
84
+ # This is because it is only set when we are ensuring all source extensions are in the destination.
85
+ is_dest_db = compared_extensions is not None
86
+
87
+ # If this is a destination database, we need to check if the owner can create objects.
88
+
89
+ if is_dest_db:
90
+ owner_ok = (r["users"]["owner"]["rolcanlogin"]) and (
91
+ r["users"]["owner"]["can_create"]
92
+ )
93
+ else:
94
+ owner_ok = r["users"]["owner"]["rolcanlogin"]
95
+
96
+ shared_preload_libraries = "ok"
97
+ missing = []
98
+ if "pg_stat_statements" not in r["shared_preload_libraries"]:
99
+ missing.append("pg_stat_statements")
100
+ if "pglogical" not in r["shared_preload_libraries"]:
101
+ missing.append("pglogical")
102
+ if missing:
103
+ shared_preload_libraries = ", ".join(missing) + " are missing!"
104
+
50
105
  summary_table.append(
51
106
  [
52
107
  style(r["db"], "green"),
53
108
  style(
54
109
  r["server_version"],
55
- "green"
56
- if float(r["server_version"].rsplit(" ", 1)[0].rsplit(".", 1)[0])
57
- >= 9.6
58
- else "red",
110
+ (
111
+ "green"
112
+ if float(
113
+ r["server_version"].rsplit(" ", 1)[0].rsplit(".", 1)[0]
114
+ )
115
+ >= 9.6
116
+ else "red"
117
+ ),
59
118
  ),
60
119
  style(
61
120
  r["max_replication_slots"],
@@ -70,26 +129,65 @@ async def _print_prechecks(results: list[dict]) -> list[list]:
70
129
  "green" if int(r["max_wal_senders"]) >= 10 else "red",
71
130
  ),
72
131
  style(
73
- pg_stat_statements,
74
- "green" if pg_stat_statements == "installed" else "red",
132
+ shared_preload_libraries,
133
+ "green" if shared_preload_libraries == "ok" else "red",
75
134
  ),
76
- style(pglogical, "green" if pglogical == "installed" else "red"),
77
135
  style(
78
136
  r["rds.logical_replication"],
79
- "green"
80
- if r["rds.logical_replication"] in ["on", "Not Applicable"]
81
- else "red",
137
+ (
138
+ "green"
139
+ if r["rds.logical_replication"] in ["on", "Not Applicable"]
140
+ else "red"
141
+ ),
82
142
  ),
83
143
  style(root_ok, "green" if root_ok else "red"),
84
144
  style(owner_ok, "green" if owner_ok else "red"),
145
+ style(r["schema"], "green"),
85
146
  ]
86
147
  )
87
148
 
88
- if len(results) != 1:
89
- return summary_table
149
+ # If this is a destinatino DB, we are ensuring all source extensions are in the destination.
150
+ # If not, we don't want this column in the table.
151
+ if is_dest_db:
152
+ extensions_ok = all(
153
+ [e in r["extensions"] for e in compared_extensions]
154
+ ) and all([e in compared_extensions for e in r["extensions"]])
155
+ summary_table[-1].append(
156
+ style(extensions_ok, "green" if extensions_ok else "red")
157
+ )
158
+
159
+ return summary_table
160
+
161
+
162
+ def _users_table(users: dict, is_dest_db: bool = False) -> list[list]:
163
+ """
164
+ Takes a dict of user info and returns a table of the users for echo.
165
+
166
+ The users table alters slightly if the results are for a destination database.
167
+
168
+ users format:
169
+ {
170
+ "root": {
171
+ "rolname": "root",
172
+ "rolcanlogin": True,
173
+ "rolcreaterole": True,
174
+ "rolinherit": True,
175
+ "rolsuper": True,
176
+ "memberof": ["rds_superuser", ...]
177
+ },
178
+ "owner": {
179
+ "rolname": "owner",
180
+ "rolcanlogin": True,
181
+ "rolcreaterole": False,
182
+ "rolinherit": True,
183
+ "rolsuper": False,
184
+ "memberof": ["rds_superuser", ...]
185
+ }
186
+ }
187
+
188
+ See pgbelt.util.postgres.precheck_info results["users"] for more info..
189
+ """
90
190
 
91
- # If we ran only on one db print more detailed info
92
- r = results[0]
93
191
  users_table = [
94
192
  [
95
193
  style("user", "yellow"),
@@ -100,38 +198,69 @@ async def _print_prechecks(results: list[dict]) -> list[list]:
100
198
  ]
101
199
  ]
102
200
 
201
+ if is_dest_db:
202
+ users_table[0].insert(
203
+ 5, style("can create objects in targeted schema", "yellow")
204
+ )
205
+
103
206
  root_in_superusers = (
104
- "rds_superuser" in r["root"]["memberof"] and r["root"]["rolinherit"]
105
- ) or (r["root"]["rolsuper"])
207
+ "rds_superuser" in users["root"]["memberof"] and users["root"]["rolinherit"]
208
+ ) or (users["root"]["rolsuper"])
106
209
 
107
210
  users_table.append(
108
211
  [
109
212
  style("root", "green"),
110
- style(r["root_name"], "green"),
213
+ style(users["root"]["rolname"], "green"),
111
214
  style(
112
- r["root"]["rolcanlogin"], "green" if r["root"]["rolcanlogin"] else "red"
215
+ users["root"]["rolcanlogin"],
216
+ "green" if users["root"]["rolcanlogin"] else "red",
113
217
  ),
114
218
  style(
115
- r["root"]["rolcreaterole"],
116
- "green" if r["root"]["rolcreaterole"] else "red",
219
+ users["root"]["rolcreaterole"],
220
+ "green" if users["root"]["rolcreaterole"] else "red",
117
221
  ),
118
222
  style(root_in_superusers, "green" if root_in_superusers else "red"),
223
+ style("not required", "green"),
119
224
  ]
120
225
  )
121
226
 
122
227
  users_table.append(
123
228
  [
124
229
  style("owner", "green"),
125
- style(r["owner_name"], "green"),
230
+ style(users["owner"]["rolname"], "green"),
126
231
  style(
127
- r["owner"]["rolcanlogin"],
128
- "green" if r["owner"]["rolcanlogin"] else "red",
232
+ users["owner"]["rolcanlogin"],
233
+ "green" if users["owner"]["rolcanlogin"] else "red",
129
234
  ),
130
235
  style("not required", "green"),
131
236
  style("not required", "green"),
237
+ style(
238
+ users["owner"]["can_create"],
239
+ "green" if users["owner"]["can_create"] else "red",
240
+ ),
132
241
  ]
133
242
  )
134
243
 
244
+ return users_table
245
+
246
+
247
+ def _tables_table(
248
+ tables: list[dict], pkeys: list[dict], owner_name: str, schema_name: str
249
+ ) -> list[list]:
250
+ """
251
+ Takes a list of table dicts and returns a table of the tables for echo.
252
+
253
+ tables format:
254
+ [
255
+ {
256
+ "Name": "table_name",
257
+ "Schema": "schema_name",
258
+ "Owner": "owner_name"
259
+ },
260
+ ...
261
+ ]
262
+ """
263
+
135
264
  tables_table = [
136
265
  [
137
266
  style("table name", "yellow"),
@@ -142,10 +271,10 @@ async def _print_prechecks(results: list[dict]) -> list[list]:
142
271
  ]
143
272
  ]
144
273
 
145
- for t in r["tables"]:
146
- can_replicate = t["Schema"] == "public" and t["Owner"] == r["owner_name"]
274
+ for t in tables:
275
+ can_replicate = t["Schema"] == schema_name and t["Owner"] == owner_name
147
276
  replication = (
148
- ("pglogical" if t["Name"] in r["pkeys"] else "dump and load")
277
+ ("pglogical" if t["Name"] in pkeys else "dump and load")
149
278
  if can_replicate
150
279
  else "unavailable"
151
280
  )
@@ -154,11 +283,31 @@ async def _print_prechecks(results: list[dict]) -> list[list]:
154
283
  style(t["Name"], "green"),
155
284
  style(can_replicate, "green" if can_replicate else "red"),
156
285
  style(replication, "green" if can_replicate else "red"),
157
- style(t["Schema"], "green" if t["Schema"] == "public" else "red"),
158
- style(t["Owner"], "green" if t["Owner"] == r["owner_name"] else "red"),
286
+ style(t["Schema"], "green" if t["Schema"] == schema_name else "red"),
287
+ style(t["Owner"], "green" if t["Owner"] == owner_name else "red"),
159
288
  ]
160
289
  )
161
290
 
291
+ return tables_table
292
+
293
+
294
+ def _sequences_table(
295
+ sequences: list[dict], owner_name: str, schema_name: str
296
+ ) -> list[list]:
297
+ """
298
+ Takes a list of sequence dicts and returns a table of the sequences for echo.
299
+
300
+ sequences format:
301
+ [
302
+ {
303
+ "Name": "sequence_name",
304
+ "Schema": "schema_name",
305
+ "Owner": "owner_name"
306
+ },
307
+ ...
308
+ ]
309
+ """
310
+
162
311
  sequences_table = [
163
312
  [
164
313
  style("sequence name", "yellow"),
@@ -168,38 +317,251 @@ async def _print_prechecks(results: list[dict]) -> list[list]:
168
317
  ]
169
318
  ]
170
319
 
171
- for s in r["sequences"]:
172
- can_replicate = s["Schema"] == "public" and s["Owner"] == r["owner_name"]
320
+ for s in sequences:
321
+ can_replicate = s["Schema"] == schema_name and s["Owner"] == owner_name
173
322
  sequences_table.append(
174
323
  [
175
324
  style(s["Name"], "green"),
176
325
  style(can_replicate, "green" if can_replicate else "red"),
177
- style(s["Schema"], "green" if s["Schema"] == "public" else "red"),
178
- style(s["Owner"], "green" if s["Owner"] == r["owner_name"] else "red"),
326
+ style(s["Schema"], "green" if s["Schema"] == schema_name else "red"),
327
+ style(s["Owner"], "green" if s["Owner"] == owner_name else "red"),
328
+ ]
329
+ )
330
+
331
+ return sequences_table
332
+
333
+
334
+ def _extensions_table(
335
+ source_extensions: list[str], destination_extensions: list[str]
336
+ ) -> list[list]:
337
+ """
338
+
339
+ Takes a list of source and destination extensions and returns a table of the extensions for echo.
340
+ It will flag any extensions that are not in the destination database but are in the source database.
341
+
342
+ <source/destination>_extensions format:
343
+ [
344
+ "uuid-ossp",
345
+ ...
346
+ ]
347
+
348
+ """
349
+
350
+ extensions_table = [
351
+ [
352
+ style("extension in source DB", "yellow"),
353
+ style("is in destination", "yellow"),
354
+ ]
355
+ ]
356
+
357
+ for e in source_extensions:
358
+ extensions_table.append(
359
+ [
360
+ style(e["extname"], "green"),
361
+ style(
362
+ e in destination_extensions,
363
+ "green" if e in destination_extensions else "red",
364
+ ),
179
365
  ]
180
366
  )
181
367
 
182
- display_string = (
183
- style("\nDB Configuration Summary", "yellow")
368
+ return extensions_table
369
+
370
+
371
+ async def _print_prechecks(results: list[dict]) -> list[list]:
372
+ """
373
+ Print out the results of the prechecks in a human readable format.
374
+ If there are multiple databases, only print the summary table.
375
+ If there is only one database, print the summary table and more detailed info.
376
+
377
+ results format:
378
+ [
379
+ {
380
+ "db": "db_name",
381
+ "src": {
382
+ "server_version": "9.6.20",
383
+ "max_replication_slots": "10",
384
+ "max_worker_processes": "10",
385
+ "max_wal_senders": "10",
386
+ "pg_stat_statements": "installed",
387
+ "pglogical": "installed",
388
+ "rds.logical_replication": "on",
389
+ "schema: "public",
390
+ "users": { // See pgbelt.util.postgres.precheck_info results["users"] for more info.
391
+ "root": {
392
+ "rolname": "root",
393
+ "rolcanlogin": True,
394
+ "rolcreaterole": True,
395
+ "rolinherit": True,
396
+ "rolsuper": True,
397
+ "memberof": ["rds_superuser", ...]
398
+ },
399
+ "owner": {
400
+ "rolname": "owner",
401
+ "rolcanlogin": True,
402
+ "rolcreaterole": False,
403
+ "rolinherit": True,
404
+ "rolsuper": False,
405
+ "memberof": ["rds_superuser", ...],
406
+ "can_create": True
407
+ }
408
+ }
409
+ },
410
+ "dst": {
411
+ "server_version": "9.6.20",
412
+ "max_replication_slots": "10",
413
+ "max_worker_processes": "10",
414
+ "max_wal_senders": "10",
415
+ "pg_stat_statements": "installed",
416
+ "pglogical": "installed",
417
+ "rds.logical_replication": "on",
418
+ "schema: "public",
419
+ "users": { // See pgbelt.util.postgres.precheck_info results["users"] for more info.
420
+ "root": {
421
+ "rolname": "root",
422
+ "rolcanlogin": True,
423
+ "rolcreaterole": True,
424
+ "rolinherit": True,
425
+ "rolsuper": True,
426
+ "memberof": ["rds_superuser", ...]
427
+ },
428
+ "owner": {
429
+ "rolname": "owner",
430
+ "rolcanlogin": True,
431
+ "rolcreaterole": False,
432
+ "rolinherit": True,
433
+ "rolsuper": False,
434
+ "memberof": ["rds_superuser", ...],
435
+ "can_create": True
436
+ }
437
+ }
438
+ }
439
+ },
440
+ ...
441
+ ]
442
+ """
443
+
444
+ src_summaries = []
445
+ dst_summaries = []
446
+ for r in results:
447
+ src_summaries.append(r["src"])
448
+ dst_summaries.append(r["dst"])
449
+
450
+ src_summary_table = _summary_table(src_summaries)
451
+ dst_summary_table = _summary_table(
452
+ dst_summaries, compared_extensions=r["src"]["extensions"]
453
+ )
454
+
455
+ if len(results) != 1:
456
+
457
+ # For mulitple databases, we only print the summary table.
458
+
459
+ src_multi_display_string = (
460
+ style("\nSource DB Configuration Summary", "blue")
461
+ + "\n"
462
+ + tabulate(src_summary_table, headers="firstrow")
463
+ )
464
+ echo(src_multi_display_string)
465
+ dst_multi_display_string = (
466
+ style("\nDestination DB Configuration Summary", "blue")
467
+ + "\n"
468
+ + tabulate(dst_summary_table, headers="firstrow")
469
+ )
470
+ echo(dst_multi_display_string)
471
+
472
+ return src_multi_display_string, dst_multi_display_string
473
+
474
+ # If we ran only on one db print more detailed info
475
+ r = results[0]
476
+
477
+ # TODO: We should confirm the named schema exists in the database and alert the user if it does not (red in column if not found).
478
+
479
+ # Source DB Tables
480
+
481
+ src_users_table = _users_table(r["src"]["users"])
482
+ src_tables_table = _tables_table(
483
+ r["src"]["tables"],
484
+ r["src"]["pkeys"],
485
+ r["src"]["users"]["owner"]["rolname"],
486
+ r["src"]["schema"],
487
+ )
488
+ src_sequences_table = _sequences_table(
489
+ r["src"]["sequences"], r["src"]["users"]["owner"]["rolname"], r["src"]["schema"]
490
+ )
491
+
492
+ if len(src_tables_table) == 1:
493
+ src_tables_table = [
494
+ [
495
+ style(
496
+ "ALERT: Not able to find tables to replicate, check your config's 'schema_name'",
497
+ "red",
498
+ )
499
+ ]
500
+ ]
501
+
502
+ if len(src_sequences_table) == 1:
503
+ src_sequences_table = [
504
+ [
505
+ style(
506
+ "ALERT: Not able to find sequences to replicate, check your config's 'schema_name'",
507
+ "red",
508
+ )
509
+ ]
510
+ ]
511
+
512
+ source_display_string = (
513
+ style("\nSource DB Configuration Summary", "blue")
514
+ + "\n"
184
515
  + "\n"
185
- + tabulate(summary_table, headers="firstrow")
516
+ + tabulate(src_summary_table, headers="firstrow")
186
517
  + "\n"
187
518
  + style("\nRequired Users Summary", "yellow")
188
519
  + "\n"
189
- + tabulate(users_table, headers="firstrow")
520
+ + tabulate(src_users_table, headers="firstrow")
190
521
  + "\n"
191
522
  + style("\nTable Compatibility Summary", "yellow")
192
523
  + "\n"
193
- + tabulate(tables_table, headers="firstrow")
524
+ + tabulate(
525
+ src_tables_table, headers="firstrow" if len(src_tables_table) > 1 else ""
526
+ )
194
527
  + "\n"
195
528
  + style("\nSequence Compatibility Summary", "yellow")
196
529
  + "\n"
197
- + tabulate(sequences_table, headers="firstrow")
530
+ + tabulate(
531
+ src_sequences_table,
532
+ headers="firstrow" if len(src_sequences_table) > 1 else "",
533
+ )
198
534
  )
199
535
 
200
- echo(display_string)
536
+ echo(source_display_string)
201
537
 
202
- return summary_table
538
+ echo("\n" + "=" * 80)
539
+
540
+ # Destination DB Tables
541
+
542
+ dst_users_table = _users_table(r["dst"]["users"], is_dest_db=True)
543
+ extenstions_table = _extensions_table(
544
+ r["src"]["extensions"], r["dst"]["extensions"]
545
+ )
546
+
547
+ destination_display_string = (
548
+ style("\nDestination DB Configuration Summary", "blue")
549
+ + "\n"
550
+ + "\n"
551
+ + tabulate(dst_summary_table, headers="firstrow")
552
+ + "\n"
553
+ + style("\nExtension Matchup Summary", "yellow")
554
+ + "\n"
555
+ + tabulate(extenstions_table, headers="firstrow")
556
+ + "\n"
557
+ + style("\nRequired Users Summary", "yellow")
558
+ + "\n"
559
+ + tabulate(dst_users_table, headers="firstrow")
560
+ )
561
+
562
+ echo(destination_display_string)
563
+
564
+ return src_summary_table, dst_summary_table
203
565
 
204
566
 
205
567
  @run_with_configs(skip_dst=True, results_callback=_print_prechecks)
@@ -214,22 +576,53 @@ async def precheck(config_future: Awaitable[DbupgradeConfig]) -> dict:
214
576
  table and sequence in the database can be replicated.
215
577
  If a row contains any red that sequence or table can not be replicated.
216
578
  """
579
+
217
580
  conf = await config_future
218
581
  pools = await gather(
219
582
  create_pool(conf.src.root_uri, min_size=1),
220
583
  create_pool(conf.src.owner_uri, min_size=1),
584
+ create_pool(conf.dst.root_uri, min_size=1),
221
585
  )
222
- root_pool, owner_pool = pools
586
+ src_root_pool, src_owner_pool, dst_root_pool = pools
223
587
 
224
588
  try:
225
589
  src_logger = get_logger(conf.db, conf.dc, "preflight.src")
226
- result = await precheck_info(
227
- root_pool, conf.src.root_user.name, conf.src.owner_user.name, src_logger
590
+ dst_logger = get_logger(conf.db, conf.dc, "preflight.dst")
591
+
592
+ result = {}
593
+
594
+ # Source DB Data
595
+ result["src"] = await precheck_info(
596
+ src_root_pool,
597
+ conf.src.root_user.name,
598
+ conf.src.owner_user.name,
599
+ conf.tables,
600
+ conf.sequences,
601
+ conf.schema_name,
602
+ src_logger,
228
603
  )
229
- result["db"] = conf.db
230
- result["root_name"] = conf.src.root_user.name
231
- result["owner_name"] = conf.src.owner_user.name
232
- result["pkeys"], _, _ = await analyze_table_pkeys(owner_pool, src_logger)
604
+ result["src"]["pkeys"], _, _ = await analyze_table_pkeys(
605
+ src_owner_pool, conf.schema_name, src_logger
606
+ )
607
+ result["src"]["schema"] = conf.schema_name
608
+
609
+ # Destination DB Data
610
+ result["dst"] = await precheck_info(
611
+ dst_root_pool,
612
+ conf.dst.root_user.name,
613
+ conf.dst.owner_user.name,
614
+ conf.tables,
615
+ conf.sequences,
616
+ conf.schema_name,
617
+ dst_logger,
618
+ )
619
+ # No need to analyze pkeys for the destination database (we use this to determine replication method in only the forward case).
620
+ result["dst"]["schema"] = conf.schema_name
621
+
622
+ # The precheck view code treats "db" as the name of the database pair, not the logical dbname of the database.
623
+ result["src"]["db"] = conf.db
624
+ result["dst"]["db"] = conf.db
625
+
233
626
  return result
234
627
  finally:
235
628
  await gather(*[p.close() for p in pools])