From 781849fe1e8bdfdec4f3ebd7c603e070d119663a Mon Sep 17 00:00:00 2001 From: Steven Pousty Date: Thu, 16 May 2019 22:53:40 -0700 Subject: [PATCH] new content (#26) * up to date (#1) * Cleanup * Use latest version of docker * Remove Docker first * Remove more of Docker * Start Docker after installing * fixed misspecification * breaking apart the workshop --- basic-postgresql-devel-pathway.json | 11 ++ basic-postgresql-devel/.gitkeep | 0 .../runcontainers/01-running-in-containers.md | 119 ++++++++++++++++ .../runcontainers/assets/docker_ps.jpg | Bin 0 -> 29150 bytes .../runcontainers/env-init.sh | 3 + .../runcontainers/finish.md | 10 ++ .../runcontainers/index.json | 30 ++++ basic-postgresql-devel/runcontainers/intro.md | 10 ++ .../runcontainers/set-env.sh | 3 + homepage-pathway.json | 8 +- learning-resources.txt | 25 ++++ postgis-pathway.json | 10 ++ postgis/.gitkeep | 0 postgis/qpostgisinto/01-spatial-data.md | 128 ++++++++++++++++++ postgis/qpostgisinto/assets/docker_ps.jpg | Bin 0 -> 29150 bytes postgis/qpostgisinto/env-init.sh | 3 + postgis/qpostgisinto/finish.md | 11 ++ postgis/qpostgisinto/index.json | 30 ++++ postgis/qpostgisinto/intro.md | 18 +++ postgis/qpostgisinto/set-env.sh | 3 + 20 files changed, 418 insertions(+), 4 deletions(-) delete mode 100644 basic-postgresql-devel/.gitkeep create mode 100644 basic-postgresql-devel/runcontainers/01-running-in-containers.md create mode 100644 basic-postgresql-devel/runcontainers/assets/docker_ps.jpg create mode 100644 basic-postgresql-devel/runcontainers/env-init.sh create mode 100644 basic-postgresql-devel/runcontainers/finish.md create mode 100644 basic-postgresql-devel/runcontainers/index.json create mode 100644 basic-postgresql-devel/runcontainers/intro.md create mode 100644 basic-postgresql-devel/runcontainers/set-env.sh delete mode 100644 postgis/.gitkeep create mode 100644 postgis/qpostgisinto/01-spatial-data.md create mode 100644 postgis/qpostgisinto/assets/docker_ps.jpg create mode 100644 postgis/qpostgisinto/env-init.sh create mode 100644 postgis/qpostgisinto/finish.md create mode 100644 postgis/qpostgisinto/index.json create mode 100644 postgis/qpostgisinto/intro.md create mode 100644 postgis/qpostgisinto/set-env.sh diff --git a/basic-postgresql-devel-pathway.json b/basic-postgresql-devel-pathway.json index ec14fb1f..b93b0733 100644 --- a/basic-postgresql-devel-pathway.json +++ b/basic-postgresql-devel-pathway.json @@ -1,4 +1,15 @@ { "title": "CrunchyData Basic PostgreSQL for Developers", +<<<<<<< HEAD + "courses": [ + { + "external_link": "https://crunchydata.katacoda.com/basic-postgresql-devel/runcontainers/", + "course_id": "runcontainers", + "title": "Quick Intro. To PostgreSQL in Containers + } + + ] +======= "courses": [] +>>>>>>> 2930e32889613de3534aabf3bf13b86bb8514a27 } diff --git a/basic-postgresql-devel/.gitkeep b/basic-postgresql-devel/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/basic-postgresql-devel/runcontainers/01-running-in-containers.md b/basic-postgresql-devel/runcontainers/01-running-in-containers.md new file mode 100644 index 00000000..cebfe2b8 --- /dev/null +++ b/basic-postgresql-devel/runcontainers/01-running-in-containers.md @@ -0,0 +1,119 @@ +In this exercise we will introduce containers (which you may know as Docker) and then spin up our PostgreSQL instance +using containers. + +## A Little Background on Containers + +Containers have quite a long history in computing before Docker. At a simplistic level, containers "package up" applications +and their dependencies to run with everything that is needed above the kernel OS. This allows for a cleaner separation +of dependencies as the container has all the things it needs to run except the kernel. Here is +[good introduction](https://medium.freecodecamp.org/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b) +to Docker containers. Be aware that there are [other](https://containerd.io/) container runtimes and specifications besides +Docker. + +Containers are spun up from a container image. In this class we will use "container" to denote the running container +and "image" to denote the binary used to spin up the container. + +Another advantage of images is that not only do they container the binaries for the application but they also are configured +and ready to run. With a container you can skip most of the configuration and just do some version of "container run" + +In this class we will be using a image that contains Postgresql, PostGIS, embedded R, and some other extensions. If +you have ever tried to install all these pieces you know what a hassle it can be. Let's see how easy it can be with containers. + +## Running PostgreSQL in Containers + +Crunchy Data has produced a full [suite of containers](https://github.com/CrunchyData/crunchy-containers) to make PostgreSQL +simpler and easier to run in containerized environments. Today we will be using a container that was purposefully built for +developers. The container makes some tradeoffs +1. It has the most used extensions already included in the binaries +1. It only requires one environment variable - a password. Everything else is optional +1. It doesn't require any volume mappings but allows for optional ones +1. Its target user is a developer on their primary development machine +1. Its not supported or intended for production use +1. It does not support replication or high availability scenarios + +It's goal is to get you up and running quickly and easily for your development work. + +#### Simplest method + +Let's start with the quickest and easiest way to start up PostgreSQL using a container. + +`docker run -e PG_PASSWORD=password thesteve0/postgres-appdev`{{execute}} + +If you click the little check mark in the box above it will execute the command in the terminal window. +What you are doing is telling docker to run image +[_thesteve0/postgres-appdev_](https://cloud.docker.com/u/thesteve0/repository/docker/thesteve0/postgres-appdev) and pass +in the environment variable for what you want the password to be for both the standard user and the postgres (DBAdmin) user. + +1. The default name for the primary database will be: mydb +1. The default username is: rnduser2w3 +1. The default port will be: 5432 +1. And the postgres user password will be equal to the user password which you set in the command. + +**CONGRATULATIONS you just spun up a fully working PostgreSQL database with a bunch of functionality!** + +But this is a pretty simplistic way to start PostgreSQL - great if you wanna just "get going quickly". + +Because we didn't run the container in "detached" mode we never got our prompt back. Detached mode allows the container +to run in the background and give us back our prompt. To shut down the container click on tab titled "Terminal 2" and +find out information on our running container: + +`docker ps`{{execute}} + +![dockerps](assets/docker_ps.jpg) + +Please note either the name or the ID of your running container (highlighted in red above). Now in the same terminal type +in the following command: + +`docker kill ` + +Docker kill is the way to stop your running container - it send the shutdown signal to the running container which should +kill the primary process in the container (in this case the PostgreSQL server process). +If you go back to the first tab, "Terminal" you will see that you get your prompt back. Let's start PostgreSQL more +appropriately for your daily work. + +#### Better way to start the container + +Let's set a new username, give the container a fixed (rather than random) name, expose port 5432 from the container +into the VM we are running, and have it detach so we can get our prompt back. + +`docker run -d -p 5432:5432 -e PG_USER=groot -e PG_PASSWORD=password -e PG_DATABASE=workshop --name=pgsql thesteve0/postgres-appdev`{{execute}} + +And with that we have now spun up PostgreSQL with +1. The ability to connect from our VM to the instance running in the container +1. Username: groot +1. Password: password +1. A database named: workshop +1. A container named: pgsql + +If you want to now log into that running instance of PostgreSQL you can do: + +`psql -U groot -h localhost workshop` + +We don't need the port mapping because the psql cli assumes PostgreSQL to be running on port 5432. + +#### A little container management + +The good part about naming the container is that we can do things like - stop the container + +`docker kill pgsql`{{execute}} + +and the start it again with all the same setting as last time + +`docker start pgsql`{{execute}} + +or + +`docker restart pgsql`{{execute}} + +Not only will this retain the setting but all the data you added before will be there when you restart the container. + +If you wanted to have PostgreSQL instances with different data or even different versions you could start up images into +containers with different names. This way you could spin them up and down as needed. + +If you want to see all the images on your machine just do the following command: + +`docker images`{{execute}} + + + + diff --git a/basic-postgresql-devel/runcontainers/assets/docker_ps.jpg b/basic-postgresql-devel/runcontainers/assets/docker_ps.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d5d2c0098436ea1a136b48b30438f85cf1ce1ee0 GIT binary patch literal 29150 zcmeFYcT|(zw=NoK(vdD*=^g0`2qMx%L_m6pigY2;g9M`Vj-Y^og7gkjLg=G$kVv(GvAH^#Yp|8>V5cjaA4#(3YA%(=>3b3V^pm%lHU0M{Ps8R`M9 zTmb;CkY0exd4LXpoQ&+Bi=1?k3dL1Q3R0n=x=MMKmWGawmWGy=o`IQ>p8gs=EiEG( z(=}!mR#sLzMm7#M77o&PmVbWa%0DeBD5xnZsafc0=~@2MxbQb#wRd^A89N0tdf|h>VJkiH(a-`|vS6BlFYeto(w) zqT-U$vhuq623RA!skx=AyQjCWe_-(E#N^cU%pyC$Hbdz(O~ZJyK@4`N ztpqY-wNuN&!DDdx*VUJ1^Y{CT=F`~741Wy2iP@RI1PCCQF9AE*+laFpPl5HK6+zz! z+S5mOMS~hUCfm3$QrYhB(fR30*%^BLOK&|S%#YJQs`;uOo?HS>*%HyF=O>%O9hNDl zUo;D_sNNRMnvzXhL{yu;Q@O`a?yjHf53?lpI&V{n&*|LO+KG4yLs4&caLz#MG>r1M zkdLblE&<T^l&(}_! zY~eJm)aiig>RV5B_1*RDit(T~z_VGGb7;34EX;u^Lm3oJlo?b0s%|g~k-^+mx0s$| zHK}c#Sc?wn3#82_34cfW9*_3m4J&h;&M_DV?@C}$e}WT;IhvZ3QyMZF+%KGvy%|1Y zGpps2q4%Uh@Y`(_XURlCnE&7x2zl5E|7J7(N~*gpV+u!i=v^!IYqsl^HWq zAn(c1&ruuF<;)*dI-7QvT-oo4`s<(HpUSa6L9cTAshV+NcMKi4xGSx2?!4!je*c$fSmJ=_F$84dPzpG~VvC*;leg6A`h{67cn*@2Rxh<}wTcXVrEfs2RJ0*yte{+AMCGfMzuj(o< z;WbE}82J!VZ{&1f)A1bJQ{9SHN0;N7bZ~p^rFg3+i00`$EGTyO?|K8mGaqLXz&ii% z7d;uJp&>1q!fWkcLXU9J9<7L6R&%stdQgc6cS`SQ!)Ttn>c)XSQ|jwJHn#y*Vecn| z&)4tayH;K;@2Sq3Tu4gcjESL-g9ppBfk9`6#Dp`{I`AqO)Rk#v`xV~H#Jruu(o~n~ z6fI@Kn54Y|`JVpLvMI9fY1H-8`li40qu;i*>I0GxJ@_{HJba7MSJ~07GK>S%5;1N& z{x`(@Dw4}_!TEh#xL6D=Pv$4N>!K|J9AL|SOy+JBV`dd_Zo#^fFS0{+>iH)nnPV9> zvFVqGoZ&&*uT_Jba*jB=ps{9zC-_d>i}fdNFJ{6-@tzj2@m+5bQ=SE-u|IZmdoMUC zy$Id_8Ve{?L%O*`w{j1i4dP}TP@xZXfK}bz_awJ znO__{*&&}@(*9fmCbhZc=V#-&XK2;7YEIN^K1^H!)|@2<4J+JT@yf1;w)1-$nV73T zc;x87Aw4IHY&d^@u{JD60b?$v_30%4_^XvvTbJ)($!SK)|U*Q}w6LFYCAYsR_uQ{2a ze*?Ee9Bi^4ZWU#ALlG9$#PSQK&kZRNXQItmtscialWi}=W+1m@?4Do`HV&@P{&5Iq zUR(VlahnHQ-c3QKJt9lc#M3>;q%eX(X1JJyJZ$CSooSIth>Z7{(?ZosZJm&jM*P-| znBi0*RLq?}foQ|({Uz7VeI9V;u{*wA>2TV*5w(+Vqd5i-P(;s)FMFWo}7~}|KP4sI! zJl1QG|FxU@H#R)#fY&F-$6h8S945ey&p0>2yO(U|NLxFNVw1zLKt@aQ^wy zOW67QV}&=fV`{QxxZK{{YnnH}CC4tAb|Cs~qH0G=u+nM1!9tdkunU@ZMSt~I+kgu1 z_nqIfQ;@spDkn@y->?zdC7F0D+qkLLSg{MqaM8nojLCvdR&%Jk*tmpCOs-o07H5?T zoi50d>6=%c+e<@)E_N8qOjwy9whv}d(Dj4pib9l|ZBk!uwT;8(>~TsRW@e8g+B*BZ zGVzM}j_%W%Z_rmmE)l(p+{@V6$y@;n4@tKeBO|S58El_``oNlW6W1ebK7uJrPckkb??L& zn)+mhbN|9_WxwW>FS9!(%JByNL&fjz0(aYAS&v%M+tZ0Pp2dTHR5>E4R*=d9w;!+2 zpZ&JPTk)nCsa!sAO1CE6L_iI@JwEUZgLIkrJLu}0`f&WTiuZXuIb7pI;<9K*3|`#} zlN4fbkt2!+il8SoRBQe)vE5Bzi|<-Jy0I&RzJ7&&IPVECnsz|JS0bw~1tZ4|*1_n# z!@l$0gIIxZzQ^ZQwUf>Vduz4GO)ohLj`%x~r(4$sDt%_^zGQtdGjW|9q0ut7`%9q6 zRkR-}DV~6a#RZx;t$x+&J}a)OEKV(Qho7`G)O||pTAW+?TFCX2`iHdjGh8Ch0Tdl} z&67Jf5kyeM40)M!wIoHyly22f6%@Dmy_gyCd>^eUeh(_3eTE=kGUpC&RCQ;X-+yt=bX*yD@RBOSoPF^0vHewY^=3>M{YJ-4tVtgX zh9558nrzPuSKbt!0PTMkJHI{&GK{$665(@ri<$zokgR?8bqW8=?8jRsL%K2@+h_jN zL!Wo2r2;mIff^i8rmYNQSZ=6aF{;<8q9LK=PkVi3kn?q^*iVUfEN}1?E`8yKW1tk^ zlum{D-sQXGc4H!KDZk*xCMFrv#U}gWse0&v6{{(vXjPFTaSTe|A#Uu$0;aQrWegd> zGu#Sdy15fMK)i1PF;O>}?b{Ukg+yr$>b}3=ofW_>GMID&X%Mx_2r9z8@#Qw0#+yjB zltc|9Q0aj4fvAmcOHtb+%X_9d_iPN~HGTDbLbT)#iMb1lt0M5Di@@`JPivfnCO5uC zM)c4kv#UecSkA;CXYZ(?EK+4#P&l=I5bhCeC=?)^SW(8yY`+j9wkv~4a$N3521I5h zt^fYJe-#{tL{feZ*JsPpElhq(o~Ss`bGFvz-OyuxY*AwTDjVp>X6y54Gp1YMdSm1n z5^vH|qMJPDoomYd=n~*+&7k?_-uFz`E8(` zdj2blYyRCjs(vJ{5`6drDHfxwMUSrpKScG^FX&?S8MZ54B8AfmX_Vj|KL^J1dwIf% zc2^Ldhw)*9jalBZ+RA(H$p`4Epxhn;JgOoUG!nzPQA08N3@Thl2s<(GibxKQjRU}e<&!f^<(;iYp4xYBb8IJ~15-+tUG zcS^c97+tU%2s}hz0zNS4|4&W2|Nj>MZ|^H8ua+|`3n?cyf@%)R*toZ^>lIU7VZLry zWm^y1%QkVD*=}BSwRv>V=G6VL&~>ltq3PPHPZ{-yjGvwY{$=$Sa}%8cd?*INLbx+6 zIt>wSyl=P7^=jQ{{PeYi)JiIpT^$y(Lc>tc0kauCF#aiCb&!=gm-1#R(~ z?F|6HS1|(-Lz^(*gU}59Jt_QdQ0&J7kH#~ql!C!fnMx|?&61p8q+p#wd9X)$b+ZD? zV=9S7hH(OOg&T@FOvrb6@yKWf`2JEIx0%Yy)JT*7Y`36i)J_!%)Bj( zGtH50urP6FzXW*0y?+ueygP_7lP*o(Tto7HT^cgMFi)7{7w=OGl-%^{%eMJ(Z}27H zSY)4oy9D&l65NPA?U#TYE&SOfASu*=H0zh3-ApXtJ-cD=kr1Y<-~#kp9OXw};6o^y zzdem8#pxruhdsl_b160MVo%VBC|QEkbD5mhyg$16_=UpOV94-8FHPjJ zLb-J$`LE^#TEMTXiBk_V)HG(x`1m?FHwouJ6FjAc6`h258(*l!C1BD07;!wzd9nY6kAA+n;*H4;Znq5Effs5}Lc`V~?s{H{CC1sQtlJVGZ%GC=Z)Z^^!VJ4?)(z z!w|8do>9}9pfW31Hhf0n?`ofW900ju4(7u!%Bh=~gB_O2+KRez*jd$`C z`+=as$8;kotHZ>$xn~N>yUQJPL`fF&r2#)PK+0XRe2>L&>gCR{vX1_^#!d8S#EGUD zPOGcJ%gMe2pAwP}eK}h0VL9PGv*|^jKXdB?)nfAAw*fvxdn-G;#Ik$CSA%WP_cJ64 zG|X(m*EMPTtbzpXe2Nd1gPukmXk0yKIU$nf=<+sE>3@>5)dWfYqeZ{lBr!)4I~uvS z(mvszJRCX-rhfAs3?vz!qb+l!H+V>|WF&)r|T59Kk@<}TDljQBaaFV`@Ft$GEhWjbzx zIY}E#q#0(YM@VP-uUpM(8{AKrL4)&JLvP`u*kV1)z}2VW3c9ZBN$I<{H(jxJv+JN- zMUV99CId4VJ9eRM<_jJq+1N;c<9`g;l$BaQZ~oP$loub~29b|0dB8}+`bq49w4!&? z6?0@i=8cLsAZ>N42&cI#0ncBz-Th?RQ>n=hyE9oLQ6f2()#gg=2 z^IK<$yP*0fIe+>RWV&T%4D<{s!uu(FY$x-#ZWqlMLKb!|0rGZ1Ug?*Bnjcthsojd2 zxq9@D)^$RF*fDQJr@&lGQf7?OB>?`%W!?g2bo62Zw1|G35+pkFLSEy}b-}joP65)g zuO$9@vj{Ky{curz%Ik>Fvl}kDJI-l5Dbiq+w;GM?jhubJLURewzb#nnJz}`e2RxcJ z4pp|2OF!sy5Z>unxdhk+b;OK(w1U~VEz*;aMnvb?ej-G=LuFPY=(x3Mw_4dKLEL}- zx|nAG@`mK7QkuS^w~J(X#Q}?9bpcwxdx571O4DYFfzlI1+VOE^-OJ*YuNt}oN{wZb zb4A)FoQZw7Ovyp+Oi3!cZv*TeGK&kU=M(V7O8}L#gl|(Z{1PB~2@r-wWuUafw| zRTqH*&|+An+UwmLOvhj51Z2QkZZ4T?=cEqPf+ow`58n^6(v4y>eMA;7{*5uSFYNA= zh975)({x^a6htv!rvMrHnaik?bzp0>IT@(XXz*j{wff;xQ+>UR~ivZC$n} zxBic=WP1q7HHy+uMWZ6sO8)!)=84l!YnDTMdNoIk0D&Fr-~<`dUA zzUUSdmw>p-2lBXXHbq_os82_@7I|Z*1t&sUi3}yDpho1DxZz_$J3G-5K~O;LY0Bq! zq~YK{9GKAkKbY7}YUVBq`fc^&maLW8nm*o`eA(0nyC<~pegA_=&b?m4-y7PUrCM&I z;W_;H5G<-IGmQOv#;C*Cp5Qpdd%~fu!=*?i*DHj}Li+xdHT&KufD3t_=VwDDluIUR zb-Q3^SmY`v+gb5U`&Wcfg}q9`;3hP35d>Xj*ayd7mw;!} z4fA(wGJ}10!)2;({nBQAtIccq0-}KTtHD>0#;n`AO*l)hei=yN9yCLgXq?{5dO9up z>cNj8ie#LUi8!qVJ2j($5Wr$k>D$Tr{3vt;35oJ@hSno8Q0YgSPx3#8(@;E%e|Z0Y zn2Y~zHvZM8)U+l8UP`9}+n=oAvs}RiOXB=7lacNJsTw)Idy?rF{6uJ=z_%yQIS{GC z_m)gCYg?0Do8*Y}w_E~}Vc97$mQOYpIkA)@W&Du=t?Tf#GpSOxhr%qCKa1}K?kK3< z_;Nt@YyEofU_1PPh!_z3@-;I=Kx-WM6z_@Vd`q%pLQBSD*ll-iXio}^&$TNTsmdZP zK{3kfr!S?IQ)}Finjw6Bo?bT?(PzSl+F0am_+X0X3BdNgY`1W*w3vR|q%LqGu<6?d zx!9xHUpVUX*xmCBhMin1{_@A_C6To5QkSQ!CV&EA40tDW?mGx)nH%>VHFyl@*@Q+A zW$)ig_?yT^mD%zprcbjh_FaKqmjJVnLyIFX5W2mlGl{i#48n(9LEf=iF$aq{g?J$06}OV;Xm`lSbI9ouwMC zOQVhU1YNtS={6m&N(b#ASGaiw^3IEtkb8kQ%p3X-y|!pXb655q)l4zxrmzM zY*Ed@Bw;k$tqR2tHUnM3ulG1|w|({&!yZ@ol^7|=jtl8X=~*-WNFQCcwvbq`FRt8S zGu6HIuO~}Qfu;sQb4-(UZo%y=s9Wm1{buEEUkZ+X%gR~#4!;ug?rY-;y}4&X7W7mK zb8M>4&}{;u=80`96u1Ui*9~Pw?|PzpPdX7S;PU;YOF;C>l!jKt<{OCn1)?JItG82& zYarQnG}VGnBGV__L=|xqaaBVOr_StptNGA8Tt5}wweO2|(OF(*NMay>^q|7GNME%s=)o-muiiEqn-qB#jcs;@U_2n`) zcm;x$lI)&%Svmlpgu8PiM?yZ06`EH*_hTvRTBkV7@epr7P~-Q}OeBAf!##{)lAsuZ zZdMXk`u!?^XK;d5EB1S`b8Lj6B zc?41i0Xg3+?#n(#%|t%-pxqzB1!}yBKZ^%O@Y817Otx7Ce*;(`_xh*3#UZ> zOzQj3eDC`3{m_i2@YVp$pH8~xEzDZoh^Sm9;tf0k4T}AS?LuzwOULx6oQ+2775HLx zgNx@hHpWL@9(LVMqe9xhw}>{lT~@Z|=NI~wkd7owC$ZVVa~9u-ohq(+NG%d{OYrO+ z?08R%MajEY{_dl3drAqpbRAW1jD$IM**Cbu3YI}ke-_%2o^J}HyDZw88ZF}-S1O*}uZp2pc&v9jZHfLm8f3kxMxUk9K>a7Hgbv0|1C>y{PoNkAE*{Td(;Vyk9 zpD|GLWuv2!i1_8eN-}NY`SE~%RV7adom#v5BoDn@IfVEu_n5?P*I99>5*i z>X7FW;3ydu#VwxSYLZSXwIi3PRp0-vO%<2h^8{>UY=iGJ6Slw*}eM4b>?oT*HRdEXhT2uc*CD zy~yZ2O5ty6{gl1Ur1<1LJ5Ow4Y(sYJ!8_l{-aqkMN2BjL_{Lu1^Tgf}nTK&y``wp- zYv%gjCk0!kMO0L%kT!HL7N70LJmC3~i%2|>EH_J6t1FRNCc3+y5E;)ZXdYtCH;}+L zpi6)k!J1Rw~_c z#G7qJoUF|XLx0Q)&R=mOUeE3vWU2JqI9M>c1OKciKm}X`n5bK)slA+0wY57Vwjq8M z)kg!Mx zOX#s>Oeh@A<1KIfXJA5N}NTgMXH(&)b5IkxVRth_i@Ol(e%C`j^%P_+`*}% zQ@T~g_xVlO@1G^jCdk-c1xg+mRDL^zr&F&%>y*~rUnwPh;g{-ktI>XJKbd}%aR~^4 z=B}h4t}T4cV6DZ3Ic$uy#Ea0t1hv3+bQNcpDpAJmXo&AVP0ij)+tgC?pVYdxG~riR zW8cC^@OLIVhXr8hV|-@5 z<2F*I23n~c?sk^O)iDn8NFZyqi)7?ps57Emc{W=_kh#bsFys+lVEuC>rWZ7Xn8FF_ zUZsvQABQh;E8O4fZOl_R|Bf-NIuT55M91D<>(Izg4%$t(XsHK^IOD^_@8s66gxI2_ zP=}gtCj&q<_|_%hJBU^=PNBQgwm%xi=jb`)S*328Ic${qwnxYA$JT2>Z<>LDvbMXV z{36nJ*y;BTB7^Il3KMR`#|4!dDkm!T^XEN3wiZfuVY$J;L$b{>M9{u?O^#cUY4dzh z72b{jQ!HVp1OfX<@g`}m@+vdYdgf?0&1&*oe?CFb_F^p1%w|*2YcXCaWf=bUr<}{o zVfCSNpu$`5jb~s^!wFa}^L!@;c*VMdKaLdl&qHZB7Z!&D!)sIa|+6xdQ zvSxY?dv<3;Y8VoL(W1rMEnUF7QDob>*bI9hIMOq#qnutKbnLO~GpT*P-7 zx{AW5{w2tef-1xjrewo3KVGWg^vS=+L}Ydb1vy*St3{363R5lC0$i*=e&M*OEzH

pjC<1|F=)^-+;FtxYhr?|}8pC=MTjGVxk%w2_ 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" + An example "external_link": "https://crunchydata.katacoda.com/workshops/" means there will be a workshops-pathway.json + Inside that JSON file will be the layout for which scenarios will be in the course. + * The title of the Course you want to show up to the end user + * And then the action - which should be "Start Course" if you have content in the directory +2. + +## Setting up a future workshop +1. Go to https:://dashboard.katacoda.com +2. Log in using the account and credentials that you used to log in to katacoda +3. + +The list of available trainings comes from the pathways in the training directory. Whatever pathway you choose +will determine the home page that attendees will see when they sign in + + + For learning more on what you can do with Katacoda The main doc site diff --git a/postgis-pathway.json b/postgis-pathway.json index 5a95e523..d12baec9 100644 --- a/postgis-pathway.json +++ b/postgis-pathway.json @@ -1,4 +1,14 @@ { "title": "CrunchyData PostGIS", +<<<<<<< HEAD + "courses": [ + { + "external_link": "https://crunchydata.katacoda.com/postgis/qpostgisinto/", + "course_id": "qpostgisintro", + "title": "Quick Intro. To PostGIS" + } + ] +======= "courses": [] +>>>>>>> 2930e32889613de3534aabf3bf13b86bb8514a27 } diff --git a/postgis/.gitkeep b/postgis/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/postgis/qpostgisinto/01-spatial-data.md b/postgis/qpostgisinto/01-spatial-data.md new file mode 100644 index 00000000..65bbe5b9 --- /dev/null +++ b/postgis/qpostgisinto/01-spatial-data.md @@ -0,0 +1,128 @@ +# Working with Spatial Data in PostGIS + +PostgreSQL has the Gold Standard in spatial extensions for any RDBMs on the market - PostGIS. If you have data that has +direct spatial information, like coordinates, or indirect, such as an address, you can leverage the power of spatial +analysis to enhance the insights into your dataIn the workshopwe will barely be scratching the surface of what you can +do with PostGIS so please don't consider this exhaustive in the slightest. + +Final note before we dig in, remember that usually to work with spatial data you need to + +```CREATE EXTENSION postgis;``` + +in your database to enable all the functionality. We don't have to do it in the workshop because we already enabled the +extension when we created the DB in the container. + +#### Spatial Tables + +Let's go ahead and log in to our PostgreSQL database: + +```psql -U groot -h localhost workshop```{{execute}} + +Remember that the password is the word 'password'. + +Now if you do: + +`\d county_geometry`{{execute}} + +PostgreSQL will show you a full description of the county_geometry table. To see all the \ commands in PostgreSQL just do +`\?` (though don't do it right now). + +You will see two spatial columns: +``` +interior_pnt | geography(Point,4326) | +the_geom | geography(MultiPolygon,4326) | + +``` +You can tell they are spatial because we declared them as type Geography with the type of spatial feature in the parentheses. +The other spatial type is Geometry. I give a brief discussion at the end of the page about the difference between the two types. +Just know that Geography is perfect for data coming from most GPSs or if you want to deal with data on a continent scale. + +You can also see we made indices for these two columns: +``` +"countygeom_interiorpt_indx" gist (interior_pnt) +"countygeom_the_geom_indx" gist (the_geom) + +``` + +Making GiST indices on spatial data allows for efficient querying of the data by creating bounding rectangles and putting them +in the index. The database can then use these simple rectangles to quickly filter out which features are not in the area of interest because +geometric operations on rectangles is much quicker than complex shapes. + +#### Simple spatial query + +Let's start with one of the simplest queries, a distance query. Let's find the 3 counties closest to the geographic center +of the United States (including Alaska and Hawaii): 44.967244 Latitude, -103.771555 Longitude. + +Now let's select the id, county names, and distance from the 3 closest counties using the +[ST_Distance function](https://postgis.net/docs/manual-2.5/ST_Distance.html): + +```SELECT id, county_name, ST_Distance('POINT(-103.771555 44.967244)'::geography, the_geom) FROM county_geometry ORDER BY ST_Distance('POINT(-103.771555 44.967244)'::geography, the_geom) LIMIT 3;```{{execute}} + +This result may take a while to return because we are calculating the distance between all the counties in the U.S. and +that point so we can ORDER the results on distance from the point. But I mentioned that PostGIS was the gold standard for a reason. It has a +method to handle our use case. It's called a K Nearest Neighbor Search (KNN) with +[its own operator](http://postgis.net/workshops/postgis-intro/knn.html). + +```SELECT id, county_name, ST_Distance('POINT(-103.771555 44.967244)'::geography, the_geom) FROM county_geometry ORDER BY the_geom <-> 'POINT(-103.771555 44.967244)'::geography LIMIT 3;```{{execute}} + +When we have a spatial index on the column, set a relatively small limit (X) on the return, and we use the <-> operator, the database +"knows" to find the first X spatially closest results and THEN calculate everything else on them. Spatial indices to the +rescue! + +#### Spatial Join + +This next query will demonstrate joining data based on spatial co-incidence rather than a shared primary key-foreign key +relationship. Our example will be to join the storm location data to the county geometry data, given us the county of the +incident eventhough it is not in our original file. + +```select geo.statefp, geo.county_name, geo.aland, se.event_id, se.location from county_geometry as geo, se_locations as se where ST_Covers(geo.the_geom, se.the_geom) limit 10;```{{execute}} + +The spatial operator we use is [ST_Covers](https://postgis.net/docs/ST_Covers.html) which return a boolean if the second geometry is completely withing the first geometry. +We set the limit to 5 because we don't want to wait for all the results to return for over 48K rows. The results also show +the [state fips](https://en.wikipedia.org/wiki/Federal_Information_Processing_Standard_state_code) code which tells us +the state name given the number. This way we can check if their is a county with the name in that state as well as a +location and if they two overlap. + +#### Spatial buffer and then select + +Finally let's do more complicated query that you could not do without sophisticated spatial operations. Suppose we were +trying to put together emergency response centers in counties with high potential for storms. We are going to buffer 12 KM (about 8 miles) +off a storm even center point and then select all the counties that intersect that buffered circle. We will use a grouping +query to do a count of the storms circles per county. + +First is the query returning all the counties with 22.5KM of a storm event location: + +```select geo.statefp, geo.county_name, se.locationid from county_geometry as geo, se_locations as se where ST_intersects(geo.the_geom, ST_Buffer(se.the_geom, 12500.0)) limit 200;```{{execute}} + + +and then do the grouping and counting: + +```sql +with all_counties as ( + select geo.statefp, geo.county_name, se.locationid from county_geometry as geo, se_locations as se where ST_intersects(geo.the_geom, ST_Buffer(se.the_geom, 12500.0)) limit 200 + ) + select statefp, county_name, count(*) from all_counties group by statefp, county_name order by statefp, count(*) DESC; + +``` + +The _with x as ()_ syntax is called a [Common Table Expression](https://www.postgresql.org/docs/11/queries-with.html) +(CTE) in PostgreSQL and makes writing subqueries a lot easier. The CTE create a temporary table that exists for just +one query. The tradeoff is that they are an optimization boundary. In this case they are fine to use for the workshop but +if you use them in future work please dig deeper into the tradeoffs of CTEs. + +## Final Note + +Today we worked with a Geography type for our spatial data because our geographic extent was the entire U.S. and it +also made our calculations easier syntax wise as well as being accurate. This is also the data format you get natively from +GPS units, such as from your phone. + +In the future, if you deal with data of a geographic extent less than a province or state, you are going to need to learn +to work with coordinate systems and projections of your coordinates (basically the process to take a globe and make a map). + +The way you specify your coordinates would change, since you would now have to give the projection you are using. Local +governments, non-profits, and companies will using give you the coordinates in a projected system so you will need to learn +how to use it in PostGIS. The ideas above remain exactly the same, it's just the way you store your data will change. + +To learn more, there is a great, but slightly outdated, [discussion](http://postgis.net/workshops/postgis-intro/geography.html) in this other workshop content. + + \ No newline at end of file diff --git a/postgis/qpostgisinto/assets/docker_ps.jpg b/postgis/qpostgisinto/assets/docker_ps.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d5d2c0098436ea1a136b48b30438f85cf1ce1ee0 GIT binary patch literal 29150 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

pjC<1|F=)^-+;FtxYhr?|}8pC=MTjGVxk%w2_ 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