Howdy how's it going? My name's Davy Chappie and I've been talking about D&D for a long time. I've been playing D&D for longer and I've gotten pretty intimate with the history of D&D so that I could make a video acquainting you with the history of D&D. So when the boys in the lab announced during their D&D celebration, which they didn't invite me to, that they were going to be showcasing the next evolution of D&D in 2024, you can bet my eyebrows were raised. New versions of the Holy Trinity were announced and fans began to murmur that this could herald the coming of a new edition of our favorite fantasy dice game. Well, as a newly christened historian and long-time keeper of D&D lore, it is my duty to tell you how wrong you are. And in order to do that, we have to take a trip through time and talk about how and why TTRPGs go through their metamorphosis every few years. As always, keep in mind that the majority of this is just my opinion. So if you're not a 5D chess player like me, who knows that what this announcement really means is that we're getting 7th edition, feel free to play your games however you want. But with that out of the way, let's begin. So to understand why I'm firmly in the camp of status quo, we have to be on the same page regarding the causes that led up to the 5th edition of D&D. You may have watched my history videos on the subject, and if you have, good for you. You're ahead of the class. But the short answer is that D&D has only ever changed editions because it had to. Back when it was just plain old D&D, every once in a while I needed to change a rule that didn't make sense, and over time those rules got so numerous that Gary decided he was going to compile them into one big book that they called Advanced D&D. Now, AD&D was not a new edition. It was treated like a new game, and it was updated alongside the original D&D because they wanted a version that would appeal to normal customers, and a version that would appeal to number crunching rule monkeys. Then, in 1989, Gary had some problems with his company, got kicked out, and when the new lady stepped in, she ordered a new edition be made so that Gary would no longer be able to collect any royalties. This was 2nd edition, and it wasn't made because 1st edition was dying, it was made to be fiscally responsible. A decade later, in the year 2000, Wizards of the Coast bought D&D, and they ordered a new edition again for the exact same reason. They wanted their own version of the game that didn't have somebody else's name on it. Now you may notice that 3rd edition is the only edition that has a middle-of-the-road .5 half-edition thing going on. And that's because having a half-edition, despite the success it gained, is not really a good thing. 3rd edition had to rebrand because its rules were so unwieldy, and so many supplements and source books were being released for it that it bloated within 3 years and Wizards was scrambling for a fix, so they shaved off all the excess nonsense, slapped a .5 sticker on subsequent books to say, hey, this isn't the same bloat as before, and breathed a sigh of relief. Until the exact same thing happened 3 years later, and they had to scramble again. 4th edition got made because 3.5, for all its fun, was also an unwieldy fuster cluck that released 20 books a year, each one further fostering the cluck. 4E ended up doing… poorly. So 8 years later 5E came out, and that is the abridged story of the D&D editions. None of them happened because of a vague The Time Feels Right, they happened as a direct response to something threatening the bottom line. And even with 4E, they waited 8 years to make a new edition because they knew that doing that invalidates all of the old books, and they wanted to try getting the water out of the boat before cutting their losses and jumping ship to a new one. Rebranding is a terrifying thing, because you might find success, or you might bomb completely, and you can prepare all you want, but there's no guarantee. So why do so many other game companies do it? It seems like White Wolf is always coming out with New World of Darkness, Call of Cthulhu is on its 7th edition as of 2017, and yet still Mutants and Mastermind stands in stark defiance of publishing trends by refusing to change editions despite having rules that would be complicated for Ultron. Even Gygax was working on his own D&D 2nd edition way back in the 70s until Williams took over the company and released it herself with heavy changes. And he was publishing updates in his Dragon magazine where he talked about how D&D could have a 2nd edition, a 3rd edition, or even dare say a 4th edition. But the place that D&D was at back then and where it is now are two completely different situations. In the before times, Gygax was in a rising company that was looking for any way possible to publicize his brand. He was doing movies, TV shows, his co-managers were unearthing 17th century shipwrecks. It was a wild ride of throwing things at the wall because the company lived or died on the back of this one IP. That is no longer the case, and it hasn't been since the turn of the millennium when Wizards of the Coast bought it. Now, D&D isn't the only thing keeping the company in business, it isn't even the flagship game, that's magic.  All D&D has to do is not piss it off, and honestly, that's what 5e's been doing. Whereas 4e's lifespan was a financial disappointment, 5e had seen record sales since 2015, and profits have only increased every year since. D&D got mainstream, and the scariest thing they can do is confuse customers by changing the numbers on the books, regardless of how badly the nerd world wants to see the numbers move. Other companies don't have the luxury of mainstream appeals, so the strategic placement of addition changes have to come sooner to keep people interested. As for D&D, the numbers show that people are still interested with what they have, and more so every day. It may be that the stonk warlocks working under the soulless one have estimated the interest to dip around 2024, which is why they scheduled their new books to be released then, but being honest, Wizards is kind of slow to the roll when it comes to trends, and it's more likely that they just started working on the books now, and it's gonna take three years to finish, because writing books takes a lot of time. They just wanted to keep their product buzzing, so they gave a very sneaky next evolution tagline without actually giving so much as a name drop. It could be anything, but what it's most certainly not, is 6e. It could still be 5.5 though, just not in the way you think. When we consider 0.5 editions, we have to acknowledge that this means an addition that shares the same core rules as another edition, but with an emphasis on distancing itself from the previous versions for one reason or another. If advanced D&D came out during this time, it probably would have been called 1.5 or something, or maybe not because that name didn't work for the Lion King and it's not gonna work here. More likely, it would have been called Revised, or Essentials, titles granted to major rulebook updates within 2nd and 4th edition respectively, which did the same thing, and can generously be called the 0.5 versions of their own games. In my opinion, Wizards is just looking to rebrand the core rulebooks with a new moniker like 5e Enhanced, or 5e Turbo Mode, so that it can use the hindsight that it gained over the decade to fix the things that don't work with the current core rulebooks, like how they clearly expected short rest to be a very common thing, but didn't expect players to have a hard time not moving for a whole hour mid-dungeon, or how exhaustion was designed to be a minor annoyance, but instead it became a never-ending debilitation. Or, you know, anything about the ranger. Who knows, considering the recent push to have adventures that don't involve any combat at all, maybe they'll add some social dynamics to the classes that don't already have them. So yeah, a 5e Colin Revelations book probably isn't going to shake things up as hard as people think. I would be very shocked to find out that anything they do with the updated core rulebooks would invalidate anything else that 5e's put out, besides, obviously, the old core rulebooks. The most likely scenario is that they change a bunch of spells and abilities that supersede the old rules, and then some obscure text in an adventure suddenly has to be home brewed over because it no longer works the same way. Current fans don't have anything to fear, new fans don't have to worry about learning a whole new system, and unfortunately, old fans will probably not be swayed into picking up 5e books if they weren't already inclined to. It'll be like the patch notes for a game, and my only hope is that they refine all of the classes like they did in Tasha's so that I never have to make a ranger joke again. Buuuut that'll about do it! I hope you enjoyed this video, be sure to leave a like, comment, subscribe, ring the bell, check out all my social media in the description below, and maybe support me on Patreon so that I can have my own turbo mode in the future. But yeah, Dabby out.


People ask me my opinion of the secret and the law of attraction. If you've heard of the book, the law of attraction or the secret, there's more than one book on the subject. I think the general premise is okay. It's subject to abuse a lot. People think just positive thinking is going to get you what you want. It's not that simple. What I would agree with is the law of attraction meaning you attract what you're around because it's scientific. Self-selection bias is something you can Google. It's scientists and mathematicians deal with this all the time. So this is real. I don't know, you know, the secret and the law of attraction is a little bit magical and mystical, which is fine. I'm not saying it's not accurate. I mix feelings on it, but I do agree with it on the part that's about self-selection bias and you'll see the importance because you might be wondering why is this even important? Okay, great. If you hang out at nightclubs, yeah, everybody you hang out with is likes nightclubs. They've selected all the people who don't like nightclubs are at home.


All right, hey guys, we got a new episode of Talk of the Town, today we got a special guest, Cush been flocking. Cush been flocking, so it never stopped me, I know you're wrong. So, everybody wants to know, like why you changed your rap name? Fresh out of jail, new start, new beginning for me, I want to like brand myself a little better for me, because as some people may not know, I'm not Blicky Game, as on the top of the fact that I want to just start a new start for me, so I want to brand myself better for me, so yeah, it's a new start for me, timeline for me to turn up, you know I've been flocking, so. So are you signed or independent? I'm independent, strictly independent. Okay, okay, okay, so when you was growing up, who was you listening to?    Why in jail, is this different energy? Nah, because it was just more of nothing to do, I'm exploring, you feel me? I'm dead. Alright, so do you consider yourself a drill artist? Nah, definitely don't, I just consider myself an artist, period, I make music, you feel me, it don't gotta be drill, it could be whatever, I make music. Okay, and how did you get into music? Like, what's your earliest memory?  So y'all was like, what, like 15 at that time? Hell no, he was mad young, like mad mad young, I was probably in fourth grade when we made that song, but third grade, so I was probably like 8, 8, 7 around there. So y'all was in the booth since kids? Yeah, that's the fact, we've been doing this for mad young. Okay, so your father has been supportive of the music scene since the beginning? Okay, so when did you start taking music seriously? We started getting real serious about it when we dropped that first song in like 2015, Street Talk, when we dropped that first video, that's when we really started taking it serious. Okay, and then was the plans for you and Kay to be the dynamic duo? Yeah. Okay, alright, so what song you feel like made Jop-Pop or what song you feel like had the streets, everybody looking at y'all? We had a couple tracks, our little Street Talk trilogy, How People's Is, then we came with the trip to the 50s, we came with Ba-Vas, we came with a whole lot of, we came with FTO, like we had a whole lot of tracks and I came with my little mixtape, me and Kay gave him had to, like we had a lot of tracks that I feel like woke the streets up, that's a fact. Okay, so how do you feel about how the music scene is from then to now? Shit is kind of watered down to me now, like it's like anybody could do it now, you feel what I'm saying?  Okay, so you think it looks too easy now? Yeah, it's way too easy now, anybody could do it.  No way. I promise you. So, but you got locked up in a peak of your career, trim to the 50s, half a middle up thing, something like that, and then, so you got locked up while everybody was going up at that time? Yeah. Like, what's your thoughts on how, where everyone is now? I know it's real different from back then.  So what's make it out to you?     Okay. Alright, so what's some of your career goals? Um, career goals, definitely, to be honest, I don't know, my short term goals right now, basically I want to get on all the major platforms where all the sound artists end up on in terms of like BET, in terms of Hot 97, in terms of filming like shit like that, big radio stations like that, big platforms like that. Okay. So that's just a little PR marketing stuff, that ain't nothing crazy. Yeah. Cause you know artists be like, oh I got a hit of million views. Nah, nah, nah, that's not the goal, I'm not doing it cloud. Okay. I want to make it something, you get what I'm saying? So filming a million views ain't about nothing, I could drop a video today that might hit a million views. Okay. So a lot of people say like in your songs, you don't curse. Yeah, that's a fact. So is that on purpose? I mean, yeah, but like, no, cause I've been doing it for so long, like it's like natural to me, for me, but yeah, I'm not cursing in my songs, like that's not what I'm doing. Yeah, so you ready, you radio ready?  So like, but how did you get in that pattern of not cursing like?  So in order for y'all to make music, you have to talk about what y'all want, just y'all can't curse. That's why that was our only stipulation.  So you've been in practice that for me, yeah.  Okay, so how did the lockup, being locked up affect your artistry, you feel like?  I feel like I grew as an artist, but like, I don't feel like it's because of jail, I feel like I grew with all this when I was in jail or not, because I like music, like I'm really, this is my thing, my passion, you feel me?  Like what?  Feel it walk outside, like, yeah, you get what I'm saying? I can't go outside, I can't do what I want to do, and my family is dead for me. It's certain people that don't got family there for them, you get what I'm saying? Yeah.  For me?  Being that you came out and like, yeah, when I first came home? Yeah, that's a fact, because when I first came home, mind you, I'm in jail.   So what I think is a banger is not a banger to niggas. Niggas is not listening to what's on the radio. So what was the banger that was on the radio that they was bumping and I was like, eh, came home and that was the banger? Nah, nah, don't say it like that, because it's like, if you put this song on, niggas is going to jack it, but niggas don't listen to radio music.  So like, what I thought was a hit to niggas is not a hit to niggas. I'm making this music for the streets. Whatever they want to hear is what I got to make for me. So I had to definitely readjust my sound for me. All right, so you out, Kay is still locked up. How often do you all speak? Every day, that's my older brother and we're locked in. So does he have plans to contain music when he come home too?   Okay. He's going to go up, you know what I'm saying?  And he's definitely going to go all the way in, y'all know what I'm saying? I'm about to say y'all got to do the dynamic duo thing. Yeah, yeah, yeah, I know what's up. Okay, so people love how you pick your beats. How do you go about picking beats? I don't know. You have a set producer? Yeah, now I got producers.  I'll be working with EP on the beat. Shout out to him. I'll be working with AB Audio, you feel me? Those are my two main go-tos right now. I got a lot of producers hitting me in my email that I'm connecting with. Keep sending them beats, you feel me? I'm listening to them. Is there a producer you heard that you want to work with? No, like that got some five beats. EP was that nigga and I got up with them. So now you're going to work. Okay. Anybody else though? No, not really. Okay, so on your project, still stepping, you said that... Hold on, you said that rappers wouldn't have made it to the industry if you was home. Do you feel like that? I feel like if I had stayed home rather, the standards for music would have been a lot higher. I feel like music is nothing right now.  I make music though, I'm really better than niggas. When you mention me, you got to mention me with niggas, I really make music, you feel me? So who really makes music? The niggas that's from my era, like my son Tutu, even Sheffanam, you feel me? Niggas that make good music, you know what I'm saying?   Alright, so explain the title of the EP, still stepping, what does that mean?   So you're going to do a deluxe to that, or you want to push that over one?  Alright, a lot of artists, you know like I said, we press the views and things like that, does it bother you that your numbers aren't as high as they used to be? Nah, it just means I got a real call there, I'm going to get there, my music is good, I know it's not white, we're going to get there, somebody's going to hear it, somebody's going to like it, you get what I'm saying? So all I got to do is just keep working hard to keep dropping, a lot of people, main discrepancy with me is consistency, they want me to drop more, so for me I'm trying to work on that, it's a lot going on, for me it's not Jesse, for me please, deal with me, I'm a drop, and every time I drop it's going to be fire, I promise you, but we definitely going to pick up the pace on it. So you admit that you're not consistent?   So I'm going to drop this, y'all going to listen to this, and I'm going to give y'all something else, you feel me? Okay, so what does consistency look like to you? It's different now, it's different now, nah, nah, nah, it's different now, game we in now, from back then it's different, back then dropping once a month was acceptable, now it's not, you got to drop, you got to drop, because niggas- I feel like once a month is not bad, if you drop on visuals once a month, you can't do that no more. How often do you think we need to drop?  Now what happens is, I feel like artists make the pressure on them when you post mad trillers.   Niggas got to go make a triller to this right now, you feel me? That's what you're saying, start going crazy.  But I'ma drop though, definitely, anything from our supporters, if I'm going to change for y'all, I'ma change for y'all. Feel me, I'ma drop. So on your EP, still stepping, what song you feel like best describes you? My intro, my intro is spoken out, everything basically, feel me? Yeah, definitely the intro. So you feel like the intro straight? Yeah. Okay, and do you have any other collabs? I know you got a song with Super Gates that's on the project, do y'all got more music in the talk, or you have other collabs in the work? I got more songs with Gates, all of Piedmont's and Gates, I got some songs in the cut with him too though, I got a lot of other features in the cut too though, a lot I don't want to speak on, but it's coming, y'all going to see me collab with Niggas, I know y'all see me drop the tape, no features, I just feel me want to put something out for my fans, I feel like they want to hear me, you feel me? Yeah. So, and I said that special spot for my son, Gates. Okay, that's yourself, thanks. So definitely more features out on the way, they got to stay tuned to see who it is. For sure, for sure. Okay, and in the song ain't the same, we tap into your emotions a little bit, so what made you be so vulnerable like in that, well in this project in general, I feel like it was real honest and open with your fans? Yeah, yeah, because I feel like I've been going through so long, they really got to figure out who I am, like you get what I'm saying, they want to know like, like, like who Chris been flocking is, I'm not Chris Blakey no more, you feel me? They want to know who this new nigga is, so let me tell you who I am, you feel me? Okay. So I feel like this project was a good like, was a good introduction to my new, you feel me? My new little path I'm about to take you out on. Okay, and what's next for Chris? More music, more money, staying super rich man, you feel me? It's always going to be free K-Flock and free trial, you feel me? Free the unit, word. I'm going to say super rich, so what does a super rich artist have? A super rich artist, like what you mean? Like what makes y'all stand out from everybody else, like to be a super rich artist?  This is what we do, like niggas know themselves, niggas know. All right, all right, so tell people where to find you, where to find music? You can find me on Instagram, I could have been flocking her YouTube, super rich cartel music for me, still stepping out now or streaming platform, go stream that. Y'all saw man, we acting bad, I know it's so.


Hey guys, Shaper 1000 here Come out to grow some of the cigarette, but I chit-chat with you do a little vlog real quick Again on one of my older cameras again a different one this time Like I said, I like to break them out once in a while I May just start like Logging the vlogs that I do Mostly are going to be on the different the older cameras That I have so Want to see what you guys thought? You know just for the vlogs because you know it was really not anything important Appear in a monitor on the CCTV monitor or our security monitor Pretty neat stuff. It looks like every morning about two o'clock in the morning It looks like it's snowing in that monitor. I don't know if it's missed if it's a do I don't know it does it whether it's rained or whether it hasn't So I'm going to upload It's just a quick video. I'm going to upload it for you Probably name it something like snow in Florida or something because it looks just like snow But regardless, it's cool. So I'm gonna share that with you fix the warrant on the On the scooter you guys probably seen that video. Well, anyway, it's up. I just posted it Just added it and posted it. So that's a quick like a 10-minute video there I'm gonna be doing something tomorrow. I'll probably do another vlog tomorrow Yeah, I still gotta do my egg my 100 year old egg again I got a couple things I can do and I don't don't forget about the giveaway for Saturday and March 7 o'clock eastern time 6 central and out west it'd be a further out west. It'll be It'd be what? Yeah Anyway, I can't think right now. So You know, if it's five or six or eight. No, it'd be four right or five six seven It'd be four o'clock California out west there's Anyway, my time, you know here down here in Florida, it'll be seven o'clock We'll do a live feed by the fire if it's not too windy if it's not raining, you know It's not too cold, you know, see what what I feel like and So and whoever the winner is I'll have a I'll give you guys a Gmail that you can Whoever wins can get a hold of me through the Gmail and You know where to send The rollie to you really get a whole lot done together then fix that horn Made monkey supper. I made her a it's kind of like a Cajun It's it's my recipe is when I made up yours again. It's kind of like a Cajun style Scramble eggs so I made that for her for supper But anyway, yeah, that's about it. Just thought I'd come out smoke cigarette hang with you guys for a minute. I Don't know what else to talk about still not feeling well, but it is what it is, right? And man, I'm telling you what to try to get a hold of anybody You know to make these appointments if you don't have insurance down here, man They don't even want to talk to you. They won't return the calls.  They'd rather see you die I mean whatever happened to their oath a doctor's oath, you know that that it's not about monetary gain It's supposed to be about helping out humanity helping out, you know People and making them well, but no not anymore.    So But yeah, I've been messing around since these cameras are still sitting up here on On the desk on my desk here. It's kind of like my workbench It's an old desk that was at work and they gave it to me. It's in great shape so I use it for my workbench and Things like, you know Because I didn't our table wasn't big enough our kitchen table and I'm big enough to put all the cameras on to make that video They're not itself. I just used this But that's about it Pretty slow today. Oh, yeah, on that video with these cameras I forgot to tell you I still I still got another mic. It's a wired mic. It's got real long wire on it But it's a lapel mic You can use it on your phone or you can use it for a camera. It's got a really good sound. I Think that's the insignia. It's a damn good mic if you're not want to be, you know, if you don't need to be like if you're gonna be close to the camera just plug it in your camera and Like right now I could could have been using it So I don't know how well this is picking up, but it should be picking up all right cuz kind of quiet in here and you know But anyway Just want to say thanks for watching guys. Thanks for watching my videos Feel free to share them Download them if you if you got the means to if you got a favorite video downloaded share it, you know Re-share it whatever Share them on your social sites and all that stuff. Yeah, share the videos Thumbs up if you don't like it thumbs it down, you know, and If you want to comment way thumb thumbs down, that's fine Let me know, you know what I can do to improve the videos And if at all humanly possible, I will gladly do my best to to do that for you guys So I want to make good videos for you guys and starting to do some different things and Learning more, you know on the editing so I can you know do different things than that, you know to make it more I'm trying to my videos are still shaky.  It's a mile or so up the road there. Maybe about a mile We were going to go do that for you. But again, it was raining had plans to get the drone out again, it was raining so monkey took that opportunity She cleaned the house up and you know all that stuff, you know deep clean. She likes to do that So she did that We still got to do the racetrack the little racetrack thing. We'll do a review on it. So That's about it. That's about all my god. So I'm gonna finish my cigarette guys again. Thanks for watching Thanks for subbing and all that good stuff and I'll see you guys in the next one. You guys are great. You're awesome. You're the best All right, so we'll chat soon guys and have a good one. Shea bearer the myth of man the legend Gone for now. Bye. Bye


Okay, I'm going to plunge right on in because we have so much stuff to talk about. Specifically, we're going to plunge right in on Django 1.7 introduced native migrations and Django 1.8 introduced Django Contrib Postgres. And there's so much cool stuff in here and so little time, so let's plunge forward. The first thing I want to say is most of what I'm going to talk about in Django Contrib Postgres was done by Mark Tamlin in, believe it or not, Kickstarter or Indiegogo. I think it was Kickstarter project for it who deserves endless praise for these wonderful new features. So first I'm going to talk about migrations and everyone's going to say, wait, migrations aren't Postgres specific, why are you talking about migrations? And the reason is that a lot, some of the stuff we're going to talk about there in Enabler for other things and Django 1.7 migrations are just amazing. So if you haven't used them just, you know, go to your laptop, I won't be offended, install, move to using migrations. And thanks Andrew for those. So a quick overview of for anyone who hasn't used the 1.7 migrations or have been treating it like a black box, migrations are built around this notion of operations. Each operation in a migration moves the database back or forward through its schema migration timeline so it adds a field, adds a table that corresponds to a model, does something like that. There are lots of individual operations, but there are two super interesting ones for our point of view, which are run SQL and create extension. These are operations that are built into, that come with the Django framework, core framework now, and you can use them in your own migrations. Run SQL, probably you can guess what it does. It applies raw SQL directly to the database and now everyone's saying, oh god, it's one of those database guys talking about raw SQL, I'm going to launch again. But really, work with me here, it's very, very handy. Specifically, it's very useful for things you can't do directly in using the models yet. Like creating indexes for some new types we're going to talk about. There's also a create extension operation, which runs a create extension command. You can sort of pattern is forming in this naming convention. Specifically, the extension mechanism in Postgres, which was introduced in 9.1, something like that, is it's a little bit like pip for Postgres. It allows you to add packaged extensions into your database. Previously, you had to drop a .so file here and run the SQL here and do all this stuff, and it was just horrible. Specifically, we're going to talk about this extension hstore, which needs to be added to your database before use. It doesn't come with the core Postgres installation. A lot of this will make more sense later. At the moment, I'm just teasing you. One thing to notice about hstore is if you have it, it adds a query to every time you connect to the database, but we'll talk about that also. So that's all you need to know about the new extension facility. Let's talk about 1.8. 1.8 adds some new field types, which are array fields, range fields, and an hstore field. 1.9 is going to add some more cool stuff, but this is what we get in 1.8. So an array field. In Postgres, since pretty much the dawn of time, arrays are first-class types. You can have a single column that is an array. Now, old-school database people like their heads explode at this point because this is denormalization and this is horrible. Forget those people. They're old and in the way. This is a really, really cool feature. An array field is now a field that you can import from Django-Contrib. Postgres, and it lets you use those directly. Before, there were tons of field of things you could find on Django snippets and things like that that would let you do it, but now it's fresh out of the box. And these map into Python arrays. Why I said array here is because I'm old and in the way. What I mean, of course, is a list. One thing to remember is that Postgres arrays are a homogeneous type, unlike Python lists which are not. So you pick a type, ints, strings, something, and that's what you get in a Postgres array. Python will let you put, of course, anything you want in a list, but don't do that if this is what you're trying to model. So, the other thing is that Python multi-dimensional arrays are rectangular. Remember Fortran? Just like that. Isn't it great that we're honoring our ancestors in this way? So they're traditional multi-dimensional arrays. They're, we say, I'm going to create a three-dimensional array with dimensions of five, seven, and ten, and the whole thing appears in this populated for you. They can be not, individual entries can be null if you need to represent a hole in the array, but it's not like, it's not like a list of list structures where each individual element can be any size you want. So once you've got it, as the dog chasing the car said, now that you've caught it, what are you going to do with it? You have array field queries. The basic one is contains. The contains matches if the array field on the left contains all the, all of the entries of the list on the right. So, A, B, C contains A, B, but it does not contain A, D. Order is not important in a contains query. So you can, you, they can, they can appear at anything in any order you want. You can also have contained by, which is effectively the reverse. Matches if the list on the right contains all the entries of, of the field on the left. So this, this is not contained by that, and that is not contained by that. But that is contained by that. We. Order's not important here either. Okay, that's easy. And then you have overlaps. So, which is the any version of, of this. So, this overlaps this, but that does not overlap that. And those, and those return a Boolean, then you also have the, the predicate underscore underscore len, which returns the length. Which returns the length of the field on the left as an integer. So, this is kind of approximate syntax. You wouldn't actually write this in your Python, but you get the idea that if it's storing this value, you apply length to it, you get two. Now, something to remember about this is that unless you've created a particular, an expression index, which we'll talk about in a bit, this is going to do a full table scan. It will pick up every single row in the database that, for that table, rattle it to calculate the length and, and filter it.  You can also apply transformations to it, such as an index. This takes, like, for example, this filters on everything whose first element underscore underscore zero is, is the string A. If there's no array zero, entry zero, for example, the, the, the, the array is of length, is of length zero. It, it doesn't match. It, it simply returns false. There's no error. So, if you put five million there and there are no five million length arrays, you'll just get back false for everything. One thing is directly, you can't specify this programmatically. You, you built in a, you built in a zero there. Unless you're going to do, you can do string substitution and use quarks to do that, of course. You can also slice the array, which is pretty cool. You can say, okay, anything whose entries zero to one are that. Or, probably more useful, zero to two contains A. You can also index array fields. So, you can just say dbindex equals true. And you're done, right? Wrong. Sorry. This, it creates a b tree index on the array, which is pretty useless for an array. So, this is one of the downsides right now of using these is you have to, if you want indexing on them and you almost certainly do want indexing, you have to do some special magic. So, let's talk about that. But first, let's talk about how Postgres does indexing. Postgres supports different kinds of index, which most people who are just using the Django arm never see because you only get one kind out of post, out of it, which is, unless you're using Django, which is a b tree index. B tree indexes are great. They're really, they're nearly the optimal solution to a particular problem, which is they're very fast, they're compact, and they provide total ordering. So, you can walk a b tree index up one side and down the other. You can use it to accelerate queries like greater than, less than or equal. It's, b tree indexes are great, but they're not perfect. Specifically, a b tree index requires a totally ordered type, like integers. Every integer is greater than, less than or equal to another integer. Those operations apply to any two integers. Strings are totally ordered. Floats are totally ordered. Points arrays in each source and things like that are not totally ordered. What does it mean for one array to be greater than or less than another? Well, you can make up something. You can say, well, we're going to compare the elements in order and then, you know, all that. But most people don't use arrays that way. That's not a very interesting way of using an array.  What you want to do is say, does this, I want to find all the instances of an array that contain this particular element, no matter where they are in the array. So, Postgres has you covered. It has two different types of indexes, which are just engine indexes. For those studying along at home, if you just sort of understand for generalized index storage technique engine stands for generalized inverted index. So now you know. Genindexes are generally used for types that contain keys and values. Arrays, in that case, they just contain values, not keys. HStores and JSON are good examples of things that are key value pairs or just value lists. Genindexes are generally used for that kind of data structure. Justindexes are generally used for types that partition a mathematical space. So like a point or a range or a rectangle is an example of something that would be indexed using just. If you want, talk to me in the whole, and I can explain the details on this for the moment, just roll with it. And the good part is once they've created, they just work. You don't have to do anything magic to them once you have them. They're updated and maintained and managed and dumped and restored and everything, all the good stuff happens to them in Postgres. So we support Genindexes, generalized inverted indexes. The nice part is these accelerate contains contained by an overlaps.  It doesn't help length or slice operations though, so be aware of that. So what this looks like at the SQL level is you create an index on app underscore model using Gen field. That using Gen is the part that indicates that what you want is a Gen type index. One thing to notice Gen can be large, especially if there's a lot of data, if there's a lot of data in the underlying table, and they're not free to update. Just don't, you know, run around creating them just cause, create them if you are going to be doing the operations that will be accelerated by them. Specifically, if it's a small table, don't create a Gen index. You know, you're throwing, it's, unless it's a pedagogical exercise for yourself, for some. If, let's say you want to index length, for example, a very common query is, get me all the arrays that, where the length is greater than seven. I'm having a hard time coming up with an example of why you'd want to do this, but the world is wide, so people do this. What you can do is create an expression index. Array underscore length is Postgres' array length operation. With the field, you have to tell it which dimension you want the array, the length of. Remember, multi-dimensional arrays? So dimension and dimension numbers are one based. Why yes, Postgres was invented in the early 90s. Why do you ask? You can also index slice operations like that. So if you're going to be doing a constant queries on does this slice equal that slice, you can do those. The double parans indicate this is an expression index, so it's actually going to calculate this expression for each entry in the table and stuff it into an index for you. Postgres is smart enough that when you do the query and it sees a matching expression, it will use the index instead of running the expression again. So that's pretty cool. Also, Postgres arrays are one based as well. What can I say? It seemed like the thing to do at the time. Okay, so now we have all this good this machinery for doing array fields, but why would you ever want to use an array field? Well, the first one is the underlying data really is an array. You want to store an array. You're getting things like, for example, a very common situation is you're recording raw sensor input from a sensor and the sensor is hand saying, okay, at this timestamp I recorded 23 samples, here they are. And you want to just dump this into a field. You could denormalize it, sorry, not denormalizing it, and create two tables. One for the base sensor and one for each of those, but wow, that's a lot of overhead. So just stuff it in an array field. One of the best uses for an array is this a replacement for a many-to-many table. One of the things that, so for example, the classic social networking problem, you have things and you have people and people like things. Now, in your basic relational database model, the way you build this is you build an intermediate table that has a many-to-many table between people and things and every time someone likes a thing you insert an entry into this many-to-many table and then you have one billion people and 12 billion things and that's kind of a, you know, 85 petabyte many-to-many table. Huh, okay, probably not. So what you can also do is, in the people field, store an array of everything they like and in the thing field, store an array of everything that everyone who likes this thing. The entries in an array can be key fields, so these can be integers that index to a to the other side, much more compact and efficient to query and then you index each field. I'm not sure I would build Facebook this way, but if you have a smaller system, this could work very well. You could also use this for denormalizing the results of an expensive query. For example, you're doing that, you're caching the results of a query, you might keep them the many-to-many field for some other reason but have an optimization where you're storing it as a denormalization. Denormalizations like this generally need to be approached with caution. I won't say never do them, but because you do have to worry about maintaining them, make sure the data stays up-to-date, things like that, but it can be very useful. Okay, and now we have each store fields. Who's ever used each store in Postgres? Okay, so each store is a semi-built-in hash store data type. It's like a dict, a Python dict, that can only take strings as keys as values and values. So it's a single level, it has to be a string on each side. Pre the JSON type in Postgres, this was the only way of storing unstructured data, associative data like this. It's not super powerful and you notice the semi in semi-built-in and we'll talk about what that means. So first of all, how do you get each store to work? Because if you log into your average Postgres database and try and create an each store a column, you know, create table, blah, blah, blah, x, each store, and it throws an error saying I have no idea what the each store type is, because it's not actually built into Postgres. It has to be installed in a particular database before you can use it. It's not part of core. The good part is Django Contra Postgres comes with an each store extension that will install it for you. So you create a custom migration and we use an empty migration, add the each store extension to operation to it, and it'll apply it and you're done. So that's good. There's this one weirdness which only really matters if you're really pushing the performance of your database and for some reason you're not using connection pooling, which you should be. The problem is that it has to do, every time you connect to the database, Psychopegee 2, which everybody's basically using if you're using Python, has to connect to the get the object identifier for the each store type because it could be different in every database. So this adds one query to the connection. It's usually not a big deal, especially because Django has this thing about asking all sorts of questions for the database on every connection, like what your time zone and things like that. So one more query among friends. But you do have to be aware that's what's going on. If you see this query fly by, now you know what's going on. So each store types are represented in Python as a dict. The keys and values must be strings, not integers, not lists, not anything else. They're translated to and from the database encoding. So if your database is in something besides UTF-8, they'll be translated to the right encoding on inside of Python. Please say your databases in UTF-8 because it's horrible if it's not. Really don't do that. So it makes database DBAs cry. But if in the off chance it's not in UTF-8, it'll do the translation for you. Each store supports contains and contains by. Both the key and the value have to match in this. And you have has key, which matches fields containing a particular key. So that's cool. And you have a has keys which takes a list. So that's pretty useful. And then there's a keys which returns the list, which matches the list of the keys in the field. So you can say, give me the, give me all the fields whose, rows whose field has keys which contain either A or B. So that's pretty cool. And values does the same for the values of the h-store field. So you can query on values as well. H-store fields support GIN indexes. So exact same syntax at model. And accelerates contains, has key, has keys, but not contains by. Sorry, just the way GIN, just the way the GIN index is built for an h-store. So why would you use an h-store field? So it's great for storing very rare attributes. Andrew actually touched on this at his talk, his great talk earlier about database anti-patterns. What, which is, you write a CMS or some other system, even an inventory control system or something like that and you send it to the customer.  And you don't want, you want the customer to be able to add attributes to items. For example, an inventory control system you might want to be able to tell people, okay, for the item they want to be able to add ISBN if it's a book or color if it's a thing that comes in colors or sizes, but not every item is going to have that and you don't know when you ship your product out to the customer which attributes they're going to want. Well you could create fields, individual fields in the database, but that's first kind of hard in Django and second of all that way, madness lies from a migrations and implementation point of view. Well, but what you can do is create a single h-store field and put use it as the place to store all of these random attributes. Generally, my rule of thumb is if there are going to be fields that are null 95% of the time consider an h-store field instead. But one thing to remember in this in this use is that null fields take zero space in PostgreSQL. They don't actually take any room on disk, so you're not costing any space by creating null fields with zero use. So and another use for these is if you have an attribute that's populated very, very, very rarely that it's not worth creating a whole field for, this is another solution to that. And user defined attributes which we just talked about. That being said, if you're doing greenfield development right now you probably want to use JSON instead especially once 1.9 comes out and we have first-class JSON support in Django. But if you have to do something right now there's no JSON type in 1.8, so use JSON if you need it right away. Or you're trying to plug into an existing database which has h-store. Now in increasing order of coolness we now come to range fields. PostgreSQL now has native range types. Range types span a range of a scalar type. So for example 1.8 as in for range includes all of those. That this is an inclusive range, so it includes those guys. You can also write them as exclusive bounds. So for example 1.8 it goes from 1 to 7 but doesn't include 8. So far so good. And that's the default. Notice that this is the PostgreSQL syntax. Obviously you can't write this in Python and have it be syntactically legal. That would be awfully cool, wouldn't it? But there are languages that will let you do that. Anyway, but this is input. So the default and the default is this open on one and closed on one side open on the other range. If you omit a bound it means all values greater than or less than. For some types, particularly dates, also have a special infinity value. I guess there's a special end-of-days value in types, I don't know. So if you see one of those coming out of a query, you might want to. PsychoPG2, the database adapter that pretty much there's no reason not to use and if you're using Django you have to work hard not to use it. Includes a Python range base type that handles all the various boundary cases and the infinity special cases and that's what the range fields in Django are built on top of. Out of the box, 1.8 supports integer range and big integer range, so 32-bit and 64-bit integers. A float range, date time range and a date range. I am pleased to say that date time range is timestamped with time zone in Postgres because if you're using timestamp without time timestamp tz you're probably making a very bad mistake. So everybody go and make sure that you're using timestamp not timestamp tz not timestamp. End date range. So contains contained by an overlap kind of work the way you'd expect to comparing two ranges. There's also a fully less than fully greater than which is true of both the upper bounds and lower bounds of the field are greater than or less than the comparison value. So if the whole range is to one side or the whole range is to the other. And adjacent to is you is true if two ranges exactly bump up against each other there's no space between them there are no values. This is a place where the parentheses the open bound is useful because you can man on a closed bound there's no way of doing this with a continuous type. There's no way of writing two float ranges two float ranges that are closed that exactly bump up against each other because there's always another float that you can shove into there. So this is why an open range is important. There's also not less than as the fields contain does not contain any points less than comparison value and not greater than which works the other way around. Range fields use gist indexes which you could probably have guessed this syntax but here it is at model using gist field. Note that the read you'll have to for now you have to drop this into a one SQL migration. There's no way of saying this just at the Django model level. That's okay that's what runs SQL's for. All the comparison operators that we that we just described are accelerated by the gist by having a gist index on a range. So why would you use this? Well here's a problem. Let's say you you're running a hotel and your rule is don't allow two bookings for a room to be inserted in the database for the same room where the dates overlap. Okay and you want to do so how do you solve this problem? There's actually no way of solving this with traditional unique constraints because there's nothing that's necessarily unique. You could say room 102 for Monday through Friday and room 102 for Tuesday through Saturday. There's nothing you the those two taken together are not unique but they but they are still that's not valid to have both in database at the same time you double book the room. Scratch scratch scratch so how do we solve this problem? Postgres to the rescue we have a facility in postgres called an exclusion constraint which is a relatively new feature i think one two in postgres but it will allow you to to not have this situation arise. It's a generalization of the idea of a unique constraint. Let's stop for a moment and think about what unique means. Unique you can say unique says well no two values can be the same for this column when you insert them. Okay that's fine but you can also say don't allow any two values which pass the equality operator in there. Now we've said it the same thing but we've said it in a slightly different way. We've said don't allow two things that where this particular operator equality are in the database at the same time. So we could say well what if the operator is in equality? What if the operator is some other operator? So we could say don't allow two things in the database at the same time where the overlaps operator matches them. Hmm well that's interesting because now and then we say well okay and let's let you add them together. So we'll say these two fields can't pass this operator and these two fields can't pass this operator and and and. So we've generalized the idea of unique to let you use any operators in combination with and and I think an example would be very important here. We'll keep the faces. So there's a catch. You have to have a single index for all of it for this whole shebang and since range types require just index the index has to be a just index. But the problem is we talked about this example where we're using room and room is just an integer or string you know however the hotel wants to represent them. This is a scalar value and scalar values don't have just type or don't have just indexing. Uh oh we just blew it. I was there's I was going to show you this great example of how to solve this problem in Postgres and now I can't. Well of course you can because there's a module called be tree gist which lets you create these indexes on mostly simple scalar types. It's a postgres extension is part of contrib. It has to be installed in the database but it ships with postgres which means you can use the create extension migration to get it into your database. So let's talk about how we'd actually use this. So you know import the models import the date time field and here's a booking and here's the room and here's the range and okay this would probably be a foreign key to a room but you know you get it. That's easy.  Well there's the integer that Jen created for us and the room and the range and we're all set. Okay so far so good. Now we create this extension be tree gist and we add this exclusion constraint. Now notice what we're doing here is we're saying add this index where the room is equal and the date is with at and and and and is the postgres version of the of the overlaps operator. So when you do an overlaps query in Django what you're going to get is this double ampersand. Okay now let's try adding some rooms with all of this. Say we're going to add a room and save that worked. Add a room and save so because it's the same room but an entirely different range. Add a room save so far so good because same range same time range but different room. Okay room do do do one two three save oh notice however this overlaps that bang oh look it didn't let me do that pretty cool and notice that this means the constraint is being enforced at the database level sure you could write code in python that would do the query and if if it returned an overlapping range say no there's exception but but the nice part about doing in the database is if you're doing bulk imports if you have other kinds of queries you you can this means the database itself enforces it. So you should use ranges range fields represent ranges I hope you get a lot of value out of this slide um you probably figured that one out it's more natural and you get better operations than the judicial high low pair of stuff in the database and you get more database integrity and more interesting operators available now coming soon we have json fields they're not in one eight but I think they've I'm I'm almost sure they've landed for one nine these are fields that support arbitrary json structures there's still a little bit of a work in progress both on the jango side and on the json side on the postgres side postgres has two json types json and json b sorry about that json stores the raw text of the json blob white space and all it is literally the text it is in fact a wrapper around postgres' text type json b is a compact indexable representation it's a lot like it's it's similar to bson but it's a lot better um so I use json instead of json b it's faster to insert since it doesn't have to process the data it just shoves the raw text in the database and json allows for two highly dubious features that people use in json which are duplicate object keys of the same level and stable object key order these are not allowed by the there's nothing in the json spec that says that these will these features are available in json but people still use them bad people they should feel bad and it's also this is okay if you're just logging json like you have a log table that's accumulating api calls or something like that where you don't really need to process the stuff you just want to have it somewhere so json b pretty much every other application you want json b it's it can be indexed in useful ways unlike json the first coming json field in Django uses json b as its underlying representation so just roll with it json b has gen indexing json json the only kind of index is available for json or b tree indexes that treat them like strings which is pretty much useless you get these operators and the query has to be against the top level of the object in the index to be useful so you can't index you can't do a query if you have a nested json structure you can't query for a key that's way down in the structure it has to be at the top level that's being worked on you can query nested objects but only in paths that are rooted to the top level so why would you use json support in general you're logging json data you want audit tables that work across multiple schemas this is a very common problem in database in relational databases where you want a single audit table that handles all the other tables rather than having one audit table for every other table which is that way madness lies it's a nice way of pickling python objects so you can so that other tools can read them the standard libraries that pickle python objects into json kind of put a lot of cruft into them for my taste but it's it work they work and for the other things that you used to use each store for like user defined objects rare fields things like that the new fields have admin widgets that go with them that are really very cool each store in json widgets are really only good for debugging because you know you basically get the raw text spat out to you and but you know why are you using the admin for this and the unaccent filter which i'm out of time for so just read about in documentation and thank you questions if in postgres the arrays are one index the example you gave in a query set filter was zero index is jango converting the yeah it's always it's python style indexing within jango because otherwise you would probably go insane yeah so and it does the zero to one conversion for you okay cool thank you quick question about expression indexes are expression indexes be tree indexes or can they you can have be tree gen and just indexes yes it's a little bit of an advanced class but for example you i can definitely see things like if the output of the operation like a slice is is jiner just a jiner just indexable type then by all means you can have a jiner just expression index and postgres does the right thing the various geo extensions do this a lot for cool stuff so i'm used to having to be a super user to create extensions is there any hope to not need that requirement when i'm putting in migrations um nope okay yeah sadly well yeah sadly because because you could really seriously screw up your database with a with a bad create extension super user access is going to be required which is really annoying if you're example on rds where you don't have super user so in the case of that you don't use a create extension situation you write many angry letters to amazon asking for that extension on the next release sorry one more question of course do you have any tips on migrating mysql to postgres high res there's not that i can deliver in a small thing like this i will say that the actually the database layer is usually only about 25 percent of the the nightmare the rest of the nightmare is the at the application level it's not so if you've been really ruthless about your about your database agnosticism in jango you probably can get away with it without too much hassle and there are tools that will probably do it for there but a surprising number of mysql applications rely on things like the return primary key on query on query for null thing that mysql does and you know db and things like that so most of the time you spend most of the time looking for mysql isms in the code actually rather than the database there are tools out there that actually do that will do the dump and load conversion for you hi are there are there any performance improvements moving from a many to many table to an array potentially huge because the when you think about how the many to many query works it has to potentially suck up a huge ton of rows and go through these enormous indexes indexes are fast but they're not infinitely fast and so if you now there there is there are upper bounds I mean one billion row item indexes are not going to be any more fun than a billion row table but potentially you could this could be a huge win especially if you're using a gin index because the way a gin index works very quickly is it indexes so if for example if you have a key of four the gin index records everything that has a four in it and can go pull those rows potentially much faster than running through a many to many table thanks and smaller you mentioned that the new fields only will only work with JSON B what do you recommend in order if you want to use the plain JSON for those sort of dirty evaluate your life choices it's unfortunately the bear JSON type does not have a lot of that good stuff in it you can get some of it by writing if if you absolutely must you can get you can write expression fields that extract the stuff out of the that can that extract those fields out of the JSON type and index them as B tree things at at some point though you're probably better off doing the JSON B unless you absolutely must have those two misfeatures sure well if if querying isn't necessarily a goal and you just want to get access to it could you like subtext or subclass like the the field and then make it at least accessible sort of to do your own well in theory you could alter you create it and then alter the type back to JSON and probably everything will work just fine at that point I haven't tried it but it's it would certainly be worth a go the other thing of course is if you want the performance enhancement you know the the the these these small but not zero performance enhancement for on inserts that JSON has over JSON B absolutely yeah your booking example is really nifty I'm wondering a couple other things so would it be possible to create multiple conditions using the B tree gist extension if so how would you recommend accept handling you could create as in more than one predicate on the not quite sure of the question sorry so let's say that in addition to the date ranges you also didn't want certain types of rooms to be booked on yeah I mean I mean it can be arbitrary things yeah it can be essentially the only reason in that case I had to use the the B tree just hack is because I because one of the thing and the whole thing has to be the set has to be a just index but all all the indexes that are that are apparent up here in the exclusion constraint have to be of the same type so that's why I had to first the int the the the string that was the room into it if for example everything everything is a you can write exclusion constraints as any combination of Boolean predicates and it together okay so effectively there's no reason to have a situation where you could have multiple kinds of integrity errors that you'd have to you'll really hit one it'll if you had you can have 12 different exclusion constraints on the same table there's absolutely no limit to how many you can have except that of course has to check them all on every insert which could be a little bit annoying so it'll you'll only get one out it won't tell you oh by the way these 12 different exclusion constraints all failed you'll it'll hit one and then stop the insert and you'll get that one and then you can when it comes to giving feedback to a user when there's certain kinds of integrity errors how would you recommend handling that on that that's that is a little more complicated in that case you may need to I would I would actually do both both query the database in advance to get the right kind of error back to the user but still have the constraint in case you need you have other applications that don't run through the same UI that try to insert data you try and bulk load it from someplace else using the copy command or something like that that way you know because you'll inevitably what will happen is like take the room example you know your hotel's running fine and then hotels.com comes in and says we'd love to send you reservations but we have this API and you know so that kind of thing I'm sure room reservation systems are a tiny bit more complex than that example but you get the idea so do you have any insight into what might be coming in one nine and beyond with regards to Postgres well in at this point one nine is pretty well locked down so you can just read the release notes you know I'm not a contributor to that stuff directly so that would be the best example I wasn't certain of your involvement okay yeah thanks for the great talk how do you feel about the funding model of the contributions to Django for the Postgres stuff and are there any other things that you'd like to see funded in a similar way um that's probably probably a longer bigger question than I can answer right here it is interesting to me that I have very strong opinions that companies that use open source should give a little more back than they do the there are certainly features I would love to see like being able to push different foreign key foreign key cascading models specify those from from the model level for example if you want to have something other than delete be able to specify that and have that implemented by the database rather than Django implementing it but yeah getting getting money for these kinds of extensions is an issue Kickstarter is great but it does tend to be a popularity contest and it locks out a lot of developers who wouldn't otherwise have you know who are brilliant programmers but haven't worked as hard to but don't have the high profile and that's a shame I think so tell your employer to write big checks is my answer great and if you need anything done with your Postgres database give us a call and thank you