ledger: extract albums->photos join table (100 albums x 50 photos)
This commit is contained in:
1 parent
0fb2caee90
commit
974a94eabf
6 files changed
+930
No files matched your search
@@ -0,0 +1,101 @@
|
||||
id,userId,title,photo_count
|
||||
1,1,quidem molestiae enim,50
|
||||
2,1,sunt qui excepturi placeat culpa,50
|
||||
3,1,omnis laborum odio,50
|
||||
4,1,non esse culpa molestiae omnis sed optio,50
|
||||
5,1,eaque aut omnis a,50
|
||||
6,1,natus impedit quibusdam illo est,50
|
||||
7,1,quibusdam autem aliquid et et quia,50
|
||||
8,1,qui fuga est a eum,50
|
||||
9,1,saepe unde necessitatibus rem,50
|
||||
10,1,distinctio laborum qui,50
|
||||
11,2,quam nostrum impedit mollitia quod et dolor,50
|
||||
12,2,consequatur autem doloribus natus consectetur,50
|
||||
13,2,ab rerum non rerum consequatur ut ea unde,50
|
||||
14,2,ducimus molestias eos animi atque nihil,50
|
||||
15,2,ut pariatur rerum ipsum natus repellendus praesentium,50
|
||||
16,2,voluptatem aut maxime inventore autem magnam atque repellat,50
|
||||
17,2,aut minima voluptatem ut velit,50
|
||||
18,2,nesciunt quia et doloremque,50
|
||||
19,2,velit pariatur quaerat similique libero omnis quia,50
|
||||
20,2,voluptas rerum iure ut enim,50
|
||||
21,3,repudiandae voluptatem optio est consequatur rem in temporibus et,50
|
||||
22,3,et rem non provident vel ut,50
|
||||
23,3,incidunt quisquam hic adipisci sequi,50
|
||||
24,3,dolores ut et facere placeat,50
|
||||
25,3,vero maxime id possimus sunt neque et consequatur,50
|
||||
26,3,quibusdam saepe ipsa vel harum,50
|
||||
27,3,id non nostrum expedita,50
|
||||
28,3,omnis neque exercitationem sed dolor atque maxime aut cum,50
|
||||
29,3,inventore ut quasi magnam itaque est fugit,50
|
||||
30,3,tempora assumenda et similique odit distinctio error,50
|
||||
31,4,adipisci laborum fuga laboriosam,50
|
||||
32,4,reiciendis dolores a ut qui debitis non quo labore,50
|
||||
33,4,iste eos nostrum,50
|
||||
34,4,cumque voluptatibus rerum architecto blanditiis,50
|
||||
35,4,et impedit nisi quae magni necessitatibus sed aut pariatur,50
|
||||
36,4,nihil cupiditate voluptate neque,50
|
||||
37,4,est placeat dicta ut nisi rerum iste,50
|
||||
38,4,unde a sequi id,50
|
||||
39,4,ratione porro illum labore eum aperiam sed,50
|
||||
40,4,voluptas neque et sint aut quo odit,50
|
||||
41,5,ea voluptates maiores eos accusantium officiis tempore mollitia consequatur,50
|
||||
42,5,tenetur explicabo ea,50
|
||||
43,5,aperiam doloremque nihil,50
|
||||
44,5,sapiente cum numquam officia consequatur vel natus quos suscipit,50
|
||||
45,5,tenetur quos ea unde est enim corrupti qui,50
|
||||
46,5,molestiae voluptate non,50
|
||||
47,5,temporibus molestiae aut,50
|
||||
48,5,modi consequatur culpa aut quam soluta alias perspiciatis laudantium,50
|
||||
49,5,ut aut vero repudiandae voluptas ullam voluptas at consequatur,50
|
||||
50,5,sed qui sed quas sit ducimus dolor,50
|
||||
51,6,odit laboriosam sint quia cupiditate animi quis,50
|
||||
52,6,necessitatibus quas et sunt at voluptatem,50
|
||||
53,6,est vel sequi voluptatem nemo quam molestiae modi enim,50
|
||||
54,6,aut non illo amet perferendis,50
|
||||
55,6,qui culpa itaque omnis in nesciunt architecto error,50
|
||||
56,6,omnis qui maiores tempora officiis omnis rerum sed repellat,50
|
||||
57,6,libero excepturi voluptatem est architecto quae voluptatum officia tempora,50
|
||||
58,6,nulla illo consequatur aspernatur veritatis aut error delectus et,50
|
||||
59,6,eligendi similique provident nihil,50
|
||||
60,6,omnis mollitia sunt aliquid eum consequatur fugit minus laudantium,50
|
||||
61,7,delectus iusto et,50
|
||||
62,7,eos ea non recusandae iste ut quasi,50
|
||||
63,7,velit est quam,50
|
||||
64,7,autem voluptatem amet iure quae,50
|
||||
65,7,voluptates delectus iure iste qui,50
|
||||
66,7,velit sed quia dolor dolores delectus,50
|
||||
67,7,ad voluptas nostrum et nihil,50
|
||||
68,7,qui quasi nihil aut voluptatum sit dolore minima,50
|
||||
69,7,qui aut est,50
|
||||
70,7,et deleniti unde,50
|
||||
71,8,et vel corporis,50
|
||||
72,8,unde exercitationem ut,50
|
||||
73,8,quos omnis officia,50
|
||||
74,8,quia est eius vitae dolor,50
|
||||
75,8,aut quia expedita non,50
|
||||
76,8,dolorem magnam facere itaque ut reprehenderit tenetur corrupti,50
|
||||
77,8,cupiditate sapiente maiores iusto ducimus cum excepturi veritatis quia,50
|
||||
78,8,est minima eius possimus ea ratione velit et,50
|
||||
79,8,ipsa quae voluptas natus ut suscipit soluta quia quidem,50
|
||||
80,8,id nihil reprehenderit,50
|
||||
81,9,quibusdam sapiente et,50
|
||||
82,9,recusandae consequatur vel amet unde,50
|
||||
83,9,aperiam odio fugiat,50
|
||||
84,9,est et at eos expedita,50
|
||||
85,9,qui voluptatem consequatur aut ab quis temporibus praesentium,50
|
||||
86,9,eligendi mollitia alias aspernatur vel ut iusto,50
|
||||
87,9,aut aut architecto,50
|
||||
88,9,quas perspiciatis optio,50
|
||||
89,9,sit optio id voluptatem est eum et,50
|
||||
90,9,est vel dignissimos,50
|
||||
91,10,repellendus praesentium debitis officiis,50
|
||||
92,10,incidunt et et eligendi assumenda soluta quia recusandae,50
|
||||
93,10,nisi qui dolores perspiciatis,50
|
||||
94,10,quisquam a dolores et earum vitae,50
|
||||
95,10,consectetur vel rerum qui aperiam modi eos aspernatur ipsa,50
|
||||
96,10,unde et ut molestiae est molestias voluptatem sint,50
|
||||
97,10,est quod aut,50
|
||||
98,10,omnis quia possimus nesciunt deleniti assumenda sed autem,50
|
||||
99,10,consectetur ut id impedit dolores sit ad ex aut,50
|
||||
100,10,enim repellat iste,50
|
||||
|
@@ -0,0 +1,602 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"userId": 1,
|
||||
"title": "quidem molestiae enim",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"userId": 1,
|
||||
"title": "sunt qui excepturi placeat culpa",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"userId": 1,
|
||||
"title": "omnis laborum odio",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"userId": 1,
|
||||
"title": "non esse culpa molestiae omnis sed optio",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"userId": 1,
|
||||
"title": "eaque aut omnis a",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"userId": 1,
|
||||
"title": "natus impedit quibusdam illo est",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"userId": 1,
|
||||
"title": "quibusdam autem aliquid et et quia",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"userId": 1,
|
||||
"title": "qui fuga est a eum",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"userId": 1,
|
||||
"title": "saepe unde necessitatibus rem",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"userId": 1,
|
||||
"title": "distinctio laborum qui",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"userId": 2,
|
||||
"title": "quam nostrum impedit mollitia quod et dolor",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"userId": 2,
|
||||
"title": "consequatur autem doloribus natus consectetur",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"userId": 2,
|
||||
"title": "ab rerum non rerum consequatur ut ea unde",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"userId": 2,
|
||||
"title": "ducimus molestias eos animi atque nihil",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"userId": 2,
|
||||
"title": "ut pariatur rerum ipsum natus repellendus praesentium",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"userId": 2,
|
||||
"title": "voluptatem aut maxime inventore autem magnam atque repellat",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"userId": 2,
|
||||
"title": "aut minima voluptatem ut velit",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"userId": 2,
|
||||
"title": "nesciunt quia et doloremque",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"userId": 2,
|
||||
"title": "velit pariatur quaerat similique libero omnis quia",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"userId": 2,
|
||||
"title": "voluptas rerum iure ut enim",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"userId": 3,
|
||||
"title": "repudiandae voluptatem optio est consequatur rem in temporibus et",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"userId": 3,
|
||||
"title": "et rem non provident vel ut",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"userId": 3,
|
||||
"title": "incidunt quisquam hic adipisci sequi",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"userId": 3,
|
||||
"title": "dolores ut et facere placeat",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"userId": 3,
|
||||
"title": "vero maxime id possimus sunt neque et consequatur",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"userId": 3,
|
||||
"title": "quibusdam saepe ipsa vel harum",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"userId": 3,
|
||||
"title": "id non nostrum expedita",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"userId": 3,
|
||||
"title": "omnis neque exercitationem sed dolor atque maxime aut cum",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"userId": 3,
|
||||
"title": "inventore ut quasi magnam itaque est fugit",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"userId": 3,
|
||||
"title": "tempora assumenda et similique odit distinctio error",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"userId": 4,
|
||||
"title": "adipisci laborum fuga laboriosam",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"userId": 4,
|
||||
"title": "reiciendis dolores a ut qui debitis non quo labore",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"userId": 4,
|
||||
"title": "iste eos nostrum",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"userId": 4,
|
||||
"title": "cumque voluptatibus rerum architecto blanditiis",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 35,
|
||||
"userId": 4,
|
||||
"title": "et impedit nisi quae magni necessitatibus sed aut pariatur",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"userId": 4,
|
||||
"title": "nihil cupiditate voluptate neque",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"userId": 4,
|
||||
"title": "est placeat dicta ut nisi rerum iste",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"userId": 4,
|
||||
"title": "unde a sequi id",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 39,
|
||||
"userId": 4,
|
||||
"title": "ratione porro illum labore eum aperiam sed",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 40,
|
||||
"userId": 4,
|
||||
"title": "voluptas neque et sint aut quo odit",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"userId": 5,
|
||||
"title": "ea voluptates maiores eos accusantium officiis tempore mollitia consequatur",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 42,
|
||||
"userId": 5,
|
||||
"title": "tenetur explicabo ea",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"userId": 5,
|
||||
"title": "aperiam doloremque nihil",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 44,
|
||||
"userId": 5,
|
||||
"title": "sapiente cum numquam officia consequatur vel natus quos suscipit",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 45,
|
||||
"userId": 5,
|
||||
"title": "tenetur quos ea unde est enim corrupti qui",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 46,
|
||||
"userId": 5,
|
||||
"title": "molestiae voluptate non",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 47,
|
||||
"userId": 5,
|
||||
"title": "temporibus molestiae aut",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 48,
|
||||
"userId": 5,
|
||||
"title": "modi consequatur culpa aut quam soluta alias perspiciatis laudantium",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"userId": 5,
|
||||
"title": "ut aut vero repudiandae voluptas ullam voluptas at consequatur",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"userId": 5,
|
||||
"title": "sed qui sed quas sit ducimus dolor",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"userId": 6,
|
||||
"title": "odit laboriosam sint quia cupiditate animi quis",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 52,
|
||||
"userId": 6,
|
||||
"title": "necessitatibus quas et sunt at voluptatem",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 53,
|
||||
"userId": 6,
|
||||
"title": "est vel sequi voluptatem nemo quam molestiae modi enim",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 54,
|
||||
"userId": 6,
|
||||
"title": "aut non illo amet perferendis",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 55,
|
||||
"userId": 6,
|
||||
"title": "qui culpa itaque omnis in nesciunt architecto error",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 56,
|
||||
"userId": 6,
|
||||
"title": "omnis qui maiores tempora officiis omnis rerum sed repellat",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 57,
|
||||
"userId": 6,
|
||||
"title": "libero excepturi voluptatem est architecto quae voluptatum officia tempora",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 58,
|
||||
"userId": 6,
|
||||
"title": "nulla illo consequatur aspernatur veritatis aut error delectus et",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 59,
|
||||
"userId": 6,
|
||||
"title": "eligendi similique provident nihil",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 60,
|
||||
"userId": 6,
|
||||
"title": "omnis mollitia sunt aliquid eum consequatur fugit minus laudantium",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 61,
|
||||
"userId": 7,
|
||||
"title": "delectus iusto et",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 62,
|
||||
"userId": 7,
|
||||
"title": "eos ea non recusandae iste ut quasi",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 63,
|
||||
"userId": 7,
|
||||
"title": "velit est quam",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 64,
|
||||
"userId": 7,
|
||||
"title": "autem voluptatem amet iure quae",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 65,
|
||||
"userId": 7,
|
||||
"title": "voluptates delectus iure iste qui",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 66,
|
||||
"userId": 7,
|
||||
"title": "velit sed quia dolor dolores delectus",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 67,
|
||||
"userId": 7,
|
||||
"title": "ad voluptas nostrum et nihil",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 68,
|
||||
"userId": 7,
|
||||
"title": "qui quasi nihil aut voluptatum sit dolore minima",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 69,
|
||||
"userId": 7,
|
||||
"title": "qui aut est",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 70,
|
||||
"userId": 7,
|
||||
"title": "et deleniti unde",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 71,
|
||||
"userId": 8,
|
||||
"title": "et vel corporis",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 72,
|
||||
"userId": 8,
|
||||
"title": "unde exercitationem ut",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 73,
|
||||
"userId": 8,
|
||||
"title": "quos omnis officia",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 74,
|
||||
"userId": 8,
|
||||
"title": "quia est eius vitae dolor",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 75,
|
||||
"userId": 8,
|
||||
"title": "aut quia expedita non",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 76,
|
||||
"userId": 8,
|
||||
"title": "dolorem magnam facere itaque ut reprehenderit tenetur corrupti",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 77,
|
||||
"userId": 8,
|
||||
"title": "cupiditate sapiente maiores iusto ducimus cum excepturi veritatis quia",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 78,
|
||||
"userId": 8,
|
||||
"title": "est minima eius possimus ea ratione velit et",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 79,
|
||||
"userId": 8,
|
||||
"title": "ipsa quae voluptas natus ut suscipit soluta quia quidem",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 80,
|
||||
"userId": 8,
|
||||
"title": "id nihil reprehenderit",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 81,
|
||||
"userId": 9,
|
||||
"title": "quibusdam sapiente et",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 82,
|
||||
"userId": 9,
|
||||
"title": "recusandae consequatur vel amet unde",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 83,
|
||||
"userId": 9,
|
||||
"title": "aperiam odio fugiat",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 84,
|
||||
"userId": 9,
|
||||
"title": "est et at eos expedita",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 85,
|
||||
"userId": 9,
|
||||
"title": "qui voluptatem consequatur aut ab quis temporibus praesentium",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 86,
|
||||
"userId": 9,
|
||||
"title": "eligendi mollitia alias aspernatur vel ut iusto",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 87,
|
||||
"userId": 9,
|
||||
"title": "aut aut architecto",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 88,
|
||||
"userId": 9,
|
||||
"title": "quas perspiciatis optio",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 89,
|
||||
"userId": 9,
|
||||
"title": "sit optio id voluptatem est eum et",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 90,
|
||||
"userId": 9,
|
||||
"title": "est vel dignissimos",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 91,
|
||||
"userId": 10,
|
||||
"title": "repellendus praesentium debitis officiis",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 92,
|
||||
"userId": 10,
|
||||
"title": "incidunt et et eligendi assumenda soluta quia recusandae",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 93,
|
||||
"userId": 10,
|
||||
"title": "nisi qui dolores perspiciatis",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 94,
|
||||
"userId": 10,
|
||||
"title": "quisquam a dolores et earum vitae",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 95,
|
||||
"userId": 10,
|
||||
"title": "consectetur vel rerum qui aperiam modi eos aspernatur ipsa",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 96,
|
||||
"userId": 10,
|
||||
"title": "unde et ut molestiae est molestias voluptatem sint",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 97,
|
||||
"userId": 10,
|
||||
"title": "est quod aut",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 98,
|
||||
"userId": 10,
|
||||
"title": "omnis quia possimus nesciunt deleniti assumenda sed autem",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 99,
|
||||
"userId": 10,
|
||||
"title": "consectetur ut id impedit dolores sit ad ex aut",
|
||||
"photo_count": 50
|
||||
},
|
||||
{
|
||||
"id": 100,
|
||||
"userId": 10,
|
||||
"title": "enim repellat iste",
|
||||
"photo_count": 50
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,43 @@
|
||||
# Albums → Photos join (extract artifact) — ledger lane
|
||||
|
||||
Per-album table: which album, its author (`userId`), its title, and the number of
|
||||
photos it contains. One row per album.
|
||||
|
||||
## Sources
|
||||
|
||||
- `https://jsonplaceholder.typicode.com/albums` — 100 albums
|
||||
- `https://jsonplaceholder.typicode.com/photos` — 5000 photos
|
||||
|
||||
Join key: `photos.albumId == albums.id`.
|
||||
|
||||
## Columns
|
||||
|
||||
| Column | Meaning |
|
||||
|---|---|
|
||||
| `id` | album id (1–100) |
|
||||
| `userId` | album author |
|
||||
| `title` | album title |
|
||||
| `photo_count` | number of photos in the album |
|
||||
|
||||
## Result (100 rows)
|
||||
|
||||
- 100 albums, 5000 photos, 100 distinct album ids.
|
||||
- `photo_count` is **50 for every album** (uniform).
|
||||
|
||||
## Artifacts (reproduced by `extract_albums_photo_counts.py`)
|
||||
|
||||
- `2026-10-31-albums-photo-counts.csv` — the table (CSV)
|
||||
- `2026-10-31-albums-photo-counts.json` — the same table (JSON)
|
||||
|
||||
## Verification (single command, exit 0 = correct)
|
||||
|
||||
Run from the repo root:
|
||||
|
||||
```bash
|
||||
bash wizard-work/ledger/CHECK-albums-photo-counts
|
||||
```
|
||||
|
||||
The check re-fetches both endpoints, re-derives the table, and compares the
|
||||
committed CSV and JSON against the fresh extraction (parsed, so line endings and
|
||||
quoting do not affect the verdict). It also asserts the row counts, the total
|
||||
photo count and the uniform `photo_count` claim above.
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# CHECK -- albums->photos extract (Extract lane, 2026-10-31).
|
||||
# Re-fetches both JSONPlaceholder endpoints, re-derives the per-album table, and
|
||||
# compares the committed CSV + JSON against the fresh extraction. Exits 0 only
|
||||
# when the committed artifacts match. Exit code IS the verdict.
|
||||
set -u
|
||||
|
||||
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
cd "$DIR/../.." || exit 1
|
||||
|
||||
python3 wizard-work/ledger/verify_albums_photo_counts.py
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Extract: JSONPlaceholder albums -> photos join.
|
||||
|
||||
Builds a per-album table: which album, its author (userId), its title, and the
|
||||
number of photos it contains. Sources:
|
||||
|
||||
https://jsonplaceholder.typicode.com/albums (100 albums)
|
||||
https://jsonplaceholder.typicode.com/photos (5000 photos)
|
||||
|
||||
Join key: photos.albumId == albums.id
|
||||
|
||||
One row per album (100 rows). photo_count is 50 for every album (uniform).
|
||||
Outputs: CSV + JSON of the same table.
|
||||
"""
|
||||
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import urllib.request
|
||||
from collections import Counter, defaultdict
|
||||
|
||||
ALBUMS_URL = "https://jsonplaceholder.typicode.com/albums"
|
||||
PHOTOS_URL = "https://jsonplaceholder.typicode.com/photos"
|
||||
|
||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def fetch(url):
|
||||
req = urllib.request.Request(url, headers={"User-Agent": "ledger/extract"})
|
||||
with urllib.request.urlopen(req, timeout=30) as r:
|
||||
return json.load(r)
|
||||
|
||||
|
||||
def main():
|
||||
albums = fetch(ALBUMS_URL)
|
||||
photos = fetch(PHOTOS_URL)
|
||||
|
||||
# sanity: every photo must resolve to a known album
|
||||
album_ids = {a["id"] for a in albums}
|
||||
unknown = sorted({p["albumId"] for p in photos} - album_ids)
|
||||
if unknown:
|
||||
raise SystemExit("photo albumIds not in albums: %s" % unknown[:5])
|
||||
|
||||
counts = Counter(p["albumId"] for p in photos)
|
||||
total = sum(counts.values())
|
||||
|
||||
rows = []
|
||||
for a in sorted(albums, key=lambda x: x["id"]):
|
||||
rows.append({
|
||||
"id": a["id"],
|
||||
"userId": a["userId"],
|
||||
"title": a["title"],
|
||||
"photo_count": counts.get(a["id"], 0),
|
||||
})
|
||||
|
||||
csv_path = os.path.join(BASE, "2026-10-31-albums-photo-counts.csv")
|
||||
json_path = os.path.join(BASE, "2026-10-31-albums-photo-counts.json")
|
||||
|
||||
with open(csv_path, "w", newline="", encoding="utf-8") as f:
|
||||
w = csv.DictWriter(f, fieldnames=["id", "userId", "title", "photo_count"])
|
||||
w.writeheader()
|
||||
w.writerows(rows)
|
||||
|
||||
payload = json.dumps(rows, ensure_ascii=False, indent=2).encode("utf-8")
|
||||
with open(json_path, "wb") as f:
|
||||
f.write(payload)
|
||||
|
||||
with open(csv_path, encoding="utf-8") as f:
|
||||
csv_bytes = len(f.read())
|
||||
print("wrote %s (%d bytes, %d rows)" % (csv_path, csv_bytes, len(rows)))
|
||||
print("wrote %s (%d bytes)" % (json_path, len(payload)))
|
||||
print("total photos = %d across %d albums (uniform photo_count=%d)"
|
||||
% (total, len(rows), rows[0]["photo_count"] if rows else None))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Independent verifier for the albums->photos extract artifact (ledger lane).
|
||||
|
||||
Re-fetches both JSONPlaceholder endpoints, re-derives the per-album table, and
|
||||
compares the committed CSV + JSON against the fresh extraction (parsed, so line
|
||||
endings and quoting do not affect the verdict). Also asserts the row counts,
|
||||
the total photo count and the uniform photo_count claim above. Exits 0 only when
|
||||
the committed artifacts match the fresh extraction.
|
||||
"""
|
||||
|
||||
import csv
|
||||
import json
|
||||
import sys
|
||||
import urllib.request
|
||||
from collections import Counter
|
||||
|
||||
BASE = "/root/troupe-standup/wizard-work/ledger"
|
||||
CSV_PATH = BASE + "/2026-10-31-albums-photo-counts.csv"
|
||||
JSON_PATH = BASE + "/2026-10-31-albums-photo-counts.json"
|
||||
|
||||
ALBUMS_URL = "https://jsonplaceholder.typicode.com/albums"
|
||||
PHOTOS_URL = "https://jsonplaceholder.typicode.com/photos"
|
||||
|
||||
|
||||
def fetch(url):
|
||||
req = urllib.request.Request(url, headers={"User-Agent": "ledger/extract"})
|
||||
with urllib.request.urlopen(req, timeout=30) as r:
|
||||
return json.load(r)
|
||||
|
||||
|
||||
def read_csv_rows(path):
|
||||
with open(path, encoding="utf-8") as f:
|
||||
return list(csv.DictReader(f))
|
||||
|
||||
|
||||
def main():
|
||||
albums = fetch(ALBUMS_URL)
|
||||
photos = fetch(PHOTOS_URL)
|
||||
|
||||
album_ids = {a["id"] for a in albums}
|
||||
unknown = sorted({p["albumId"] for p in photos} - album_ids)
|
||||
if unknown:
|
||||
print("FAIL: photo albumIds not present in albums: %s" % unknown[:5])
|
||||
return 1
|
||||
|
||||
counts = Counter(p["albumId"] for p in photos)
|
||||
total = sum(counts.values())
|
||||
|
||||
# Fresh extraction result (same field types the extractor writes).
|
||||
raw_rows = []
|
||||
for a in sorted(albums, key=lambda x: x["id"]):
|
||||
raw_rows.append({
|
||||
"id": a["id"],
|
||||
"userId": a["userId"],
|
||||
"title": a["title"],
|
||||
"photo_count": counts.get(a["id"], 0),
|
||||
})
|
||||
|
||||
if len(albums) != 100:
|
||||
print("FAIL: expected 100 albums, got %d" % len(albums))
|
||||
return 1
|
||||
if len(photos) != 5000:
|
||||
print("FAIL: expected 5000 photos, got %d" % len(photos))
|
||||
return 1
|
||||
if len(counts) != 100:
|
||||
print("FAIL: expected 100 distinct album ids with photos, got %d" % len(counts))
|
||||
return 1
|
||||
if len(set(counts.values())) != 1:
|
||||
print("FAIL: photo_count not uniform, values=%s" % sorted(set(counts.values())))
|
||||
return 1
|
||||
|
||||
# CSV: committed file parsed with DictReader -> all strings.
|
||||
csv_rows = []
|
||||
for r in raw_rows:
|
||||
csv_rows.append({
|
||||
"id": str(r["id"]),
|
||||
"userId": str(r["userId"]),
|
||||
"title": r["title"],
|
||||
"photo_count": str(r["photo_count"]),
|
||||
})
|
||||
if read_csv_rows(CSV_PATH) != csv_rows:
|
||||
print("FAIL: CSV does not match fresh extraction")
|
||||
return 1
|
||||
|
||||
# JSON: committed file parsed -> ints for id/userId/photo_count.
|
||||
if json.load(open(JSON_PATH, encoding="utf-8")) != raw_rows:
|
||||
print("FAIL: JSON does not match fresh extraction")
|
||||
return 1
|
||||
|
||||
print("OK: %d rows match the fresh extraction (uniform photo_count=50, %d photos)"
|
||||
% (len(raw_rows), total))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user