In SQLAlchemy, check constraints are table-level objects that must be declared separately using the CheckConstraint class and attached to the table via the table_args parameter, rather than being defined within individual column definitions like primary keys or nullable constraints. This separation exists because check constraints apply to the table as a whole, not to a single column, and they act as guards that reject invalid data during insert and update operations before the data is stored in the database.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
ORMs — SQLAlchemy | AI Engineering for 365 Days | (Day 63/365) [Vertical Stream]
Added:Okay, [music] just let me be me and I'll stay out of your way. I can see the way you look at me. [music] I'm such a disgrace. I never really asked to be brought into this place. You want to love me? [singing] Well then, baby, I have a taste. [music] All the highs and the lows. No, you'll never be the same.
I don't really want to hurt [music] you, but I can't control the pain. If you're sticking by my side, maybe we could be okay. Okay. Okay. Maybe you could be the change [music] I need today. I promise that I never felt this way. I really hope that you will choose to stay through all the pain.
>> I [music] know you told your friend you're not okay and tell me what's [music] wrong and why you never said you felt that way. Guess you're trying to stay [music] and fake a smile until I look away. But [music] I've known you too long. It hurts.
>> Already Mike does seem white does thing.
Okay, perfect. Let me go to our main camera. party live and as you guys can tell by damn thumbnail today I'm going to work with more SQL alchemy using I think it was N OSQL or NoSQL that's last stream I did work with a couple of topics and this stream I will be continuing and hopefully by the end of uh next stream I will be done with my entire SQL or the entire databases this category and move on to the mini project before phase two which is math and machine learning and yeah I did think of trying out a few nerdy glasses here if it doesn't look good. I'm going to open it later on. That's it. Yo, hiding on.
Appreciate you joining the stream. Okay.
And yeah, this is a brand new Claus's chat. Let me go ahead and say something like since I am live exclamation. And yeah, I will be using touch typing this stream as well. Okay. And then let's send it. Oh, and I'm going to use let's say the extra effort level for claude cuz I may stream for longer today based on the amount of uh contents that I actually cover the stream. That's it. It says here full sand. All right, day 63.
And yeah, I made sure to update Cloud's day today. New glasses. Let's go. It does look like it does look pretty cool.
I think it I don't think that it makes me look like a nerd, but it does it does give like a nice little uh should I say look to a new fit here. Well, it's not really a new fit, but you guys can tell me that the glasses does not look better here. I think it does. Okay, that's it.
All right, day 63. Last time we stopped on purpose right at the edge of something new. That was true. We did stop uh before working with I think Yeah, I think it was like check constraints because that's how you ended a session. Clean, not messy. Check constraint is sitting right here waiting for you and we're going to get it. Quick gut check before we touch anything else.
You said you had Okay, I'm removing this for now. Yeah, I thought it looked cool, but I'm going to wear it when my eye starts to feel uncomfortable here. Okay, quick gut check before we touch anything else. You said you had a solid grasp on maps at index of whatever data type you wanted to add inside the map and map column 444 last session. No slip ups except spelling primary keith. Okay, right. Good. That's foundation.
That foundation is what's about to get tested [snorts] because check constraint does not play by the same rules as everything else you've built so far. I see I flagged this last time and I'm not flagging it again. It's a different shape of object, not a keyword argument, not something you dropped inside map columns, something else entirely. I'm not going to tell you what something else is yet. You're going to feel the shape of it yourself in a second. Okay.
So, here's your student class exactly where we left it from SQL Alchemy. I want to import my declarative base. I wanted to import mapped and I wanted to import the map columns function. And then I create a base class that derives from my declarative basis class. So, um we're we're working with inheritance here. And then I create a students class. This is going to be a single instant of every single students column inside of my database. Uh let's say nsql where I have done table name equals to student. This is like a stamp specifying what exact uh column belongs to which exact student cuz multiple students could have their own name yada yada but this is going to be giving them a separate ID. H I'm not saying anything bad about uh looks. You misunderstood me. You look good, man. With or without it. Take care. Keep learning. Actually, it does make sense. The reason I open my glasses is cuz I felt it looks kind of weird on camera as well. Plus, my lighting here, lighting here, and lighting here. It sort of reflects in my glasses. So, you guys would be seeing the lighting instead of my eyes. Well, not just that. It also kind of uh what we call it feels sort of uncomfortable wearing it when I have my headphones on, but I wear it when my eyes gets uncomfortable. That said name mapped which which is going to be a string data type equals to mapped underscore column that requires primary key okay as a parameter which is going to be set to true and it requires a nullable which is going to be false. I'm pretty sure primary key checks if there are um okay hold on let me open my Visual Studio Code. I literally went over primary key last stream as well. What the hell? Hold on. Wait here. Database.
Okay. Combine not none plus unique and mark to the column. Important. Primary key independently rechecks both conditions from scratch. It doesn't trust a reference. Okay. So basically primary key is like a guard. It's going to recheck my conditions to see if um what I set it to do if that exact thing is really happening. And well, if I did use it directly from SQL, it would check for let's say unique characters or if I have any empty characters which is set to null.
Oh yeah, I see who's here. Yo, how you doing? Uh Jade, is that you pronounce your name? I appreciate you joining the stream. Oh wait, you're kidding me. I'm in my gameplay.
No one told me that I was in my main camera and not in my gameplay screen. Oh god. Okay, guys, let me know. I sometime forget. Okay, let's see. I guess I'm growing pretty old these days. Trying to get gray hair at the age of 18. Okay, let's see. Hold on. Let me just go ahead and grab cloud out here real quick.
There we go. Okay, now now you already did this exact concept in raw SQL back in the database module. You wrote a check constraint on age with your own with your own two hands. age numeric or one which basically means I can have um a max of four characters as my age which could I mean and it can consist of a decimal point. So I could be let's say 100 years old or 100.6 years old or like 27.8 years old if that makes sense. And then I also check if my age is greater than zero. So before I explain anything about how SQL Alchemy does it. Oh yeah, that does make sense.
This was how uh PSQL did it, talk to me in plain English. No code, no syntax.
Um, no syntax guessing. What does check constraint actually do?
What was it? Oh god, guys. How many ants? Last stream I saw an ant.
Did I do it? Did I just sit there?
Here we go. Oh god. Glad it didn't me. I got to like get some freaking test in this place. Okay. Uh what was it protecting you from back in raw SQL?
Okay. So, um the check constraint. Let's go with something like the check constraint. C O N S E R A I N T. Okay.
The check constraint is in charge of filtering.
Yeah, I think that was the easiest way I could put it.
Huh, close. But I want you to sharpen that. Filtering is doing a lot of wig work. That does make sense. Filtering makes me think of where which picks out rows of a result you already have.
That's not what check does. Think back to the actual moment you used it. Age numeric for one check age greater than zero.
But that's cons. Okay, that constraint isn't looking at an existing row and filtering some out of query result. It's sitting there watching a different moment entirely. What does check actually fire? Walk me through it.
What's happening?
Check looks actually check filters based on um the condition uh that we give it to. For example, I could add a check constraint c o n s e r a i n t to let's say find students who were over the age of 18.
It would filter those students and uh let's say give me their name.
There we go. And then let's go ahead and send it.
Okay, stop. That's not check constraint.
That's select where query. Oh, you just you just described select name from students for age greater than 18. That's retrieval asking a question about data.
that's already sitting in the table.
Check is not a question. Check is a guard on the door. Here's the real sequence. You want to insert a student with age equals to -5. The moment that data tries to enter the table before it's stored, before it becomes a row, the check constraint looks at it and says, "Nope, rejected." It's not picking students out of existing data. It's refusing bad data from ever getting in the first place. Same for update. If you try to change Devon's H to five, check blocks that update too. It fires on every wire that's not on reads. So no filtering, no give me back students who match X. It's a bouncer at the door off table checking IDs where everyone gets in. Bad data gets turned away. Oh, okay.
You know what? I meant that. I said it in the wrong way. Okay, now that now with that corrected, try it again. Same question. What does check actually do and when does it fire? Okay, you know what? I was kind of wrong to be honest.
Let me say um check is in charge of being a guard.
If someone decides uh to put a bad data check um does not allow it.
Uh, I want I actually uh meant this the first time I said filter, but I should go with something like however.
I feel like the wording here was much better. Go with something like much better.
There we go. We can then I guess we're going to go ahead and send it.
Huh, there it is. Uh, that's the correct concept. And yeah, guard at the door blocking bad data out the way is completely different idea from filtering existing rows, even if it felt like the same thing in your head a second ago.
Good that you caught the distinction yourself instead of just agreeing with me. Now, here's why I made you say it out loud before touching any SQL alchemy syntax in raw SQL. Check lived inside the column definition. Age numeric 4, 1.
Check age greater than zero bolted right onto the column. Same line in SQL alchemies is OM object rational mapping.
Hold on, hold on, hold on.
What is the full form of form in SQL?
Oh god, guys, this touch typing sometimes gets in my freaking nerve.
Okay, so it's object relational mapper.
Okay, there we go. It's it's the same thing. I said rational. Okay, relational in SQL Alchemy uses object relational mapping. It does not live inside mapped underscore column. It can't because check constraint isn't describing one columns rule. It's a standalone object that gets declared separately and then attached to the table as a whole. That's the different shape I kept warning you about. Here's the mechanical pattern.
I'm showing you the shape not asking you to write it yet from SQL alchemy import check constraint class student base table students name which is mapped to a string data type that is equal to mapped underscore column I map it inside of my literal um database primary key equals to true I can go over my entire column again just to fact check if everything is going good nullable equals equals to false. My name cannot be empty. There must be a placeholder for my name. Age, which is mapped to a floatingoint data type that is mapped to be a column as well in my database. And then dunder table args. I have never heard of this, but that's all right. Equals parentheses. And then check constraint age greater than zero. A string that says age greater than zero. Two new pieces here. check constraint age greater than zero. Notice the condition is a string, not a Python code. And table underscore and dunder table underscore args, a special tpple that sits at the top of the class for anything that isn't a single columns business. Before you write a single character, prediction time. If I ran this right now and then tried to insert a student with age equals to -5, what happens? walk me through it in plain words. Um, it will not allow me to do so because of the check constraint.
Okay. Uh, that said, I have never seen our uh worked with. Let me go with something like I've never seen or worked with with I don't know. Dunder table. Uh there we go. Dunder table args. Guys, this touch typing is so stressful.
So, what does it do?
There we go. Bro, I have a recommendation. SQL just launched graph query that you can use in SQL database.
It recently launched it similar to Neo4j cipher query. Check it out and learn it too. Actually, I think I will because later on in this series, I will be going over SQL and all the topics that I have already been go that I already have gone over in phase one. But in a more advanced level, phase one is not me uh mastering every single topic. It's me just knowing that they really exist, but I don't really want to spend a lot of time learning a single topic. But to get a gist of it, and since it is new, I definitely will check it out. Huh. Also, cuz it's new, it may not be in my road map. So, that's that's something fun as well. Okay, good prediction. Correct.
And asking before guessing is exactly the right move here. Naughty gap. So, dun table_archs.
Let's build the real world picture first and then I'll tell you the mechanical reason it has to exist. Think about your students's class. Every other line you've written name age is underscore enrolled. GPA is a column. Each one belongs to exactly one thing. Mapped underscore column is built to describe a single columns personal rules. Okay.
Is it required? Is it unique? isn't the primary key. But check constraint age greater than um zero is a string. Who does that belong to? It's not really ages property. The way nully equal to false is it's a rule about the table as a whole. That does make sense. We're going to go over every single column.
They're not just one.
Oh, so that's what table_arch means.
It's not really ages property yada yada as a whole. And once you start doing more advanced things later uh like multicolumn constraints, composite indexes, foreign keys that don't fit under one column, you'll have a whole category of stuff that belongs to the table, not to any single column.
Dun table args is the designated bucket for exactly that. It's a tuple that sits outside the individual column definitions and says here's the extra configuration for the table itself, not any one field. SQL Wait, quick gut check before we move on. In your own words, no code. Why couldn't SQL Alchemy just let you write age map flowing point map uh check constraint age greater than zero the same way does it did the primary key because that check is limited to uh just the column.
However, we needed a check for the table as a whole. Also, wait, did that answer my question about the uh dunder, what was it again? Dunder table args question mark. Uh because I did not understand the purpose of it. I forgot the off there. There we go.
Huh. Okay. You're circling it, but you flip the logic. Let me pin it down exactly where map column check constraint isn't rejected because the check would be limited to the column. A check on age genuinely is about one column. The problem is something more basic. Mapped underscore column is built to accept specific keyword arguments. It already knows about primary key nullable unique. It has no argument slot uh designated to accept a whole separate constraint object dropped inside it. All right. How in the genuine world would I have known that? It's not a too narrow versus too broad issue. It's a wrong container issue. All right. I mean I didn't know that part.
Okay, dunder table_arch args. Well, dunder table args exists as uh the escape hatch for exactly that. Anything that does not fit as a keyword argument on a single column gets declared separately and handed to the table through this bucket instead. On your second question, yes, the first explanation of the undertuck for stuff about the table, not one column, is the actual answer to what it does. You had it. You just second guessed it because your check scope reasoning above was shaky. So, it felt unresolved even though it wasn't. Let's isolate it so there is no ambiguity left. Single question. No need to justify it. True or false? Table uners dunder table underscore args can only ever hold check constraint objects nothing else.
True wrong. And I want you to notice why you picked true because that's the actual bug not the answer itself. You just watched me introduce exactly one thing that goes in dunder table args check constraint. That said, one example, and your brain quietly turned the one thing I've seen so far into the only thing that's allowed. That's a pattern completion trap, not a knowledge gap.
You don't actually have evidence for only, you just haven't seen a counter example yet. Here's the counter example.
Dunge table args is a generalpurpose bucket for any table level configuration. Multicolumn unique multicolumn unique constraints.
Composite indexes or foreign keys spanning multiple columns. Even tablewide settings like which schema it lives in. Check constraint is just the first resident you've met. The bucket doesn't care what kind of table level object you put in it. So correct answer false. Okay, you know what? That actually does make sense. Okay, we ask sharpen. So I know this actually landed and wasn't a lucky guess the first time under table holds configuration that applies to a single column or the table as a whole. the table as a whole and that I think that I unerstood what dunder uh table args uh means.
It is used when we need to add constraints s e r a i s to a table as a whole, right?
God.
Hm. Yeah, I'm pretty sure uh it's used when we need to like add a constraint to the whole table, right? That's correct.
And this time it's not shaky. You've got the actual shape of it. Under table args isn't a check only tool. It's the general draw point for anything that table scoped instead of a column scope.
Good boundaries holding. Let's put it in work. We call your raw SQL version of the database module age numeric 4, 1, check age greater than O. We're rebuilding that exact rule, but now in the OM shape you just learned. Check constraint living inside dunder table args. Prediction time. Before any code exists, if I had this in your students class, dunder table arc check constraint age greater than zero. And then someone tries to insert a student with the age of zero. Exactly. No. Negative. Exactly.
Zero. What happens? Block me through your reasoning. Not just yes or no.
It's um they should be getting an error that tells them that uh the that um an age of zero is not allowed.
um because of the constraint.
Okay. And then let's send it. Okay.
Correct. And good. You're you reasoned it from the actual condition instead of just pattern matching. Check equals to block bad stuff. Age greater than zero is a strict greater than or zero fails.
It's just as hard as negative 5 does.
That's exactly right. Now you write it.
Take your current students class and add the check constraint yourself using dunder table enforcing age greater than zero. Same rule as your raw skill version. Okay. Check constraint.
So apparently this is our file here and I'm going to go ahead and let's say add a dungeon. But before that a good habit is to add comments.
Add constraints.
to the table as a whole.
Okay, so we're going to go with something like dunder table underscore args is going to be equal to a pair of curly braces. In the curly braces, I'm going to go ahead and add a check constraint.
Will intersons work? I forgot I closed my damn into lessons.
Check constraint c a i n ts is going to be equal to let's say something like uh was it check age greater than zero? I forgot that one part. Hold on.
Oh check constraints is basically it's one thing and it's title case too. Wait, it's a it's a it's a function.
Okay, I guess it's a function. So, I'm going to go with something like age greater than zero. The syntax is not hard. This is just the first time I was writing it. A control + C. We're going to copy that. And then let me just go ahead and grab plot here. Then we're going to paste it.
Then send it.
Okay, close. Really close. But there are two things to catch before I let this slide. one syntax one and that would break at runtime. First look at the class name you used. Check constraints age greater than zero with an s on the end. Oh, constraints. Well, typos. Go back and check what I actually imported and wrote earlier in this session. What was the real name? Second separate issue structure this time. Look at your parenthesis.
I told you dunder table is a tpple.
Does that code actually produce a tpple?
Well, a comma. No, wait. Should this be inside of a pair of parenthesis for actually being a it it literally isn't a pair of parenthesis. There's a trap in Python. Parenthesis around a single item does not make it a tuple. It makes it an equation.
Is just x with parentheses around it.
Nothing special. Ale needs something specific to mark it as a tuple even with wait curly braces like no wait isn't that like a set do you remember what something special is from your earlier Python object oriented programming okay I know this this was supposed to be I need multiple con All right, I I give in. Hold on.
All right. Didn't Okay, you know what? I think I said comma, but then later on I was like, never mind. Oh god, I shouldn't have taken it back. Okay. Uh I saw the reference. Oh god, this is what my uh professor also told me like god damn our professor like in my college my professor he asked us what what differentiates uh let's see an equation in a parenthesis with a tuple that time as well I thought that it was supposed to be a comma I didn't say the same exact thing happened this time I guess I'm not forgetting it again okay I saw the reference and it's a comma oh god guys that The worst thing that I've done so far should have been easy.
Yes, that's exactly it. Yada yada. Okay, so we're going to fix our typo here.
Guys, this comma is going to haunt me for a couple of days. I should have known this part.
Okay, we're going to go here and then we're going to paste it and send it.
Okay, that's it. Both fixes landed.
Constraint correct name and the trailing comma making it an actual tpple. That's a clean correct check. Constraint implementation. Nice.
We're catching both on your own. I did not catch it on my own. One thing missing before this runs though. You dropped the from salary import check constraint import line. You're using the class but never importing it. Okay, so Oh, okay. That makes so much more sense.
I thought this was a function, but class makes more sense. This does look like a class declaration. Okay, so let's go ahead and import our check.
Mercy C E K C.
Are you kidding me?
There we go. C O N S T R A I N T. Okay, perfect. Let me grab Claudia and say that I'm I I'm done importing it.
Okay, one thing missing, yada yada. That closes out check constraints. Two things left. Two things left ceued for this chunk before declarative models is fully done. The enrollment date column and the email column where unique is going to be equal to true finally gets applied instead of just talked about conceptually. Yeah, last stream we did go over the theory of unique, but we didn't really have a place to like use it. But if you're working with emails, then we will use it. Let's knock out enrollment date first since it's the simpler one of the two. You already know mapped at index of float, mapped at index of string, mapped at index of boolean from your existing columns. A date is a new territory in the object relational mapping mapping typing system. Quick check before I explain anything. Have you ever seen SQL alchemies or verm represents a date type in Python type style? No.
Okay, a clear answer is no cuz I didn't I haven't done half these things here.
Well, I haven't done 99 or 95% of the things here besides the Python programming. Okay, no worries. New syntaxes. So, full explanation before you touch it for the rule. Here's the shape. You already know the pattern. Map index of string, map index of float, map index of boolean. Python's own builtin type slotted in maps. A date isn't a Python built-in way with a string or boolean are. Python has a real date type, but it does not live in the language. That does make sense. I think we need to import the time module. Damn it. We need to import the date time. We need to import date from date and time library.
Yeah, that does make sense. But it doesn't live in the language. lives in a stand in a standard library module called datetime. Okay. So from the datetime module I want to import the dates as library. So the type becomes mapped at index of date equals to mapped column. Two new things here both small date has to be imported from date time module. It's not automatically available like string or boolean. Everything else about the pattern is identical to what you already know. Mapped at index of date on the left, mapped underscore column on the right. Same shape as every column you've already written. Okay. New exotic, nothing exotic uh beyond that import. Same pattern, new type prediction before you write it. If you now if I now try to insert a student and pass enrollment date equals to not a real date, a plain string that isn't a valid date, what do you think will happen? SQL Alchemy, will SQL Alchemy catch that or let it through?
Let's think.
Okay, let's go with something like SQL A L C H E the alchemy will catch that and we actually may get a Python error to be honest because um we add A uh wait a genuine minute.
I thought that we're going to actually get a error, but it doesn't make sense because if we write we're going to write our data as a string, right? So it should let it pass through because um need to not add a date. Now my second uh theory.
Now my second theory.
I believe that it will let it pass through because we have a string.
because we have a string and that uh when we try to insert a date, it must be a string as well.
However, that lands me to a concern.
Um that lands me to a concern about um better or not.
The uh module consists of splits uh that splits our string and um checks if our Eight is um correct using if statements and is underscore digit if that made any sense. Oh god, I I makes any sense. Okay, I made that sound way too confusing.
Okay, good instinct to wrestle with it out loud instead of just picking one.
Okay, I just wrote that whole thing cuz I wanted to just blabble on and like get all my thoughts in like a actual screen that I can later on look at cuz I would have forgotten it the next second. But I want you to slow down here because you're over complicating this in a very specific useful to catch way. You're imagining SQL Alchemy has some custom parsing engine under the hood. Splitting strings, running digit, hand rolling date validation logic. It doesn't need to. It's not reinventing date forcing from tracing from scratch.
Here's the actual mechanism. Mapped at index of date tells SQL Alchemy this column expects a real Python date object when you pass a plain string, not like a real date. Python's old type system is what catches it, not some custom SQL alchemy string splitter. It's much closer to your first theory than your second theory. This behaves like a straightforward type mismatch, not a text parsing problem.
Let's strip it down to remove the noise.
Forget SQL Alchemy for a second. Plain Python uh question. If I write from date import from date times module import date and then try date not a real date or just use no OMS involved at all. What do you think happened?
It will let it through because I am assuming the data type that uh the date function requires is a string and then we send it careful that's a response that's a reasonable sounding guess but is backwards and I want you to feel before I tell you the answer the date is not expecting a string at all think about what a calendar calendar date actually needs needs to be specific. A year, a month, a date, three separate numbers.
That's the real shape. Date wants. Okay.
How in the genuine world would I know this stuff? How would I know it? Okay.
You know what? I should have known it.
Date 2024 115, which is um year 24 month. So, January 15, 2024.
Three integer arguments, not one string.
So date not a real date isn't working string isn't wrong string content. It's the wrong number of arguments entirely.
Python would throw a type error immediately because you're handling it one string where it expects three integers. This is actually why your orm column will be safe too and not because of custom validation logic but because the moment you try to con construct a date object with garbage plain Python itself refuses because SQL alchemy is even involved. Let's rebuild this cleanly one isolated question at a time.
First what are the three pieces of information a date object needs to be created?
a year, month, oh god, and date. Guys, I can't wait to get so fluent at uh whatchamacall freaking touch typing that I can like type everything really really smoothly. For now, it does not feel like I'm typing as smooth as butter, but it does feel like I I'm getting smoother to be honest.
Should I say I'm more of in a um vaccine phase? Well, I don't know if that makes that did not make any sense.
Okay, that's it. Right idea. One word off. You said date for the third piece.
But a real date needs a day, not a Oh, I meant day. I said date. That would be circular. A date needs a date to be made. Your month day. Good. That's solid. Now, let's connect it back to the actual insert scenario since that's where since that's what we're really building towards. Second question. If I correctly build a date object like date 2024 January 15th and pass that into enrollment date column instead of a string, what happens on insert? Does the check constraint style guard at the door rejected accepted or is there nothing to guard against it at column column?
There will be nothing to guard against it at all because we do not add one and that um no one asked uh no one specified that We needed a string only for enrollment date. Okay. And then I guess let's go ahead and send it. Whoops. Smashed down my table. Okay. Let's isolate this because your answer is dodging the actual question instead of answering it.
Forget check constraints for a second.
There's no check rule on enrollment date at all. You're right about that part, but that's not what I asked. I asked something simpler. Does the answer succeed or fail when you pass a correctly built date object into column maps uh date? Think about it from think about it.
That's Oh, think about it from the first principles, not from guarding/blocking language. The column says, I expect a date object. You're handing it a date object correctly shaped correctly typed exactly what it asks for succeeds or fails.
I would say that it succeeds because I am assuming that date.
No, that it fails because I am a ss u m i n g. I'm assuming that date is a function and that we can not use functions as data types in maps.
I think that makes sense, right? Good. I can see where where the wires cross. So, let's fix it at the root instead of just correcting the answer. You're treating date as if it was one thing that can only be a function or a type, not both.
But that's not actually a contradiction in Python. Date is a class. Why is it not capitalized then? Why is it not title case? I mean, shouldn't it be title case if it's a class? Classes can be used as um as data types and calling a class date is exactly how we create. All right. All right. All right.
All right.
All right.
All right. Dot dot dot. I did not know that date was a class because it was written as date and not date.
Um, therefore it confused me and that uh with class it would make a lot of sense because uh we can use classes as data types as opposed to functions.
There we go. And then let's send it.
Okay, now we're talking that naming instinct is actually sharp. By the way, you're right that Python convention is us is usually is usually facil case for classes. I've never heard of facil case, but it makes sense for some reason.
Student declarative base and snake underscore case lowerase for functions.
date to breaking that conviction is a legitimate reason to get thrown off. Not a dumb mistake. Python's own standard library isn't perfectly consistent here.
Date, int, string, list, all are classes, but lower case. All right, I did not know that stuff. Good catch on noticing the pattern even though they even though it misled you once. And yes, that's the real that's the real unlock class work as type hints because an instance of the class is a value of that type. That's the whole mechanism. So final answer, no more hedging success or failure, typed mapped at index of date.
You hand it a real data object says correct. as the full loop close date is a class calling. Okay, go ahead and write it. Calling it builds a real instance map yada yada. There we go.
yada yada.
Okay, I'll go write it. Okay, so first things first, I'm going to go ahead and import something from my date times module. Right, the date times module. I want to go ahead and import date.
And then we're going to go ahead and create an instance of my date which I will do it up here. Not but it doesn't really matter in Python. So I'm going to do it here. I'm going to go with date that is going to be equal to date is going to be equal to wait I'm I'm creating an instance right I'm creating an instance. Hold on hold on hold on.
This is not a object.
Okay, I'm going to go with date_obj for object that is going to be equal to I'm going to go to my uh date and give it a parameter of year, month and day. Year is going to be 20 24.
Month is going to be January. Day is going to be 15. And then I'm going to copy my date obj. And we're going to paste it right here. Hit Ctrl S to save the code. A control + C. Copy that. Get replete. Then let's paste it. Hello. Uh did you see the new PostgreSQL feature?
Actually, I did not. What is the new PostgresQL feature? I did not even hear of it cuz I did not really completely master posgrql. I just went over the uh foundations and all the basic at a let's say general level. Later on in this series when I work with let's say phase five phase six that's when I will be working or like moving more into I think postgrql and SQL cuz I'm pretty sure I'm going to be working with LLMs and rack there but it really depends. Wait, what is SQL alchemy? It's another feature under uh let's say databases. I did not fully get an MD file for it yet, but so far I did like start this yesterday.
Although so far I think SQL Alchemy is how we connect our Python code to our SQL's database. For example, I'm going to go ahead and programming it. I'm going to program the stuff in Python exactly as I would program it in SQL and then we're going to just connect the both things together. That's how later on in the series I will be building a fully automated web scraper where I will be using SQL Alchemy to write the code in Python and just save my code or let's see connect my code to SQL's database.
You know what? That actually made so much sense. I'm so glad you asked that question right now. Okay. Whoa, hold up.
This went sideways in a few places. is let's slow down and untangle it piece by piece because you're mixing up two completely different things. Defining a column type versus inserting an actual row of data. Look what she wrote. Isn't road map index of boolean date obj.
Uhoh. Uhoh. Uh-oh. Uh-oh. My bad. Can we Can we like erase this from Claude's memory?
Hold on. No one's got to know I did this, right?
There we go. Did I paste the right thing? No. Oops.
Stop right there. This went sideways in a specific way again. Wait, I cheated and I still messed up. Okay, I didn't really cheat. That was that was just um whatchamacallit me being distracted while adding the data type.
And I want you to see what uh see exactly what happened before you touched it again. Three separate problems. Check constraint import location. You moved from SQL Alchemy import go back and check where did I actually import it from earlier this session. SQL Alchemy ORL OM and SQL Alchemy are not the same modules. Wait, I thought they were the same. You overwrote is undersc enrolled instead of adding enrollment underscore date.
Oh, look at your classes and road map.
Oh god, your boolean. Okay, yada yada.
Date OBJ date at the bottom. This is a symptom of number two. You created one specific hard-coded date value and tried to use it as if it were a type. But mapped wants a data type date, not a specific value. That's the same confusion as mapped string wanting the concept of string.
Hey, you know what? That makes sense actually. So, we're going to fix those errors. I'm going to just copy this constraint and I'm going to go with something like from SQL alchemy. I want to go ahead and import.
Oops. I want to import I want to import check constraints.
Let's go with C.
H E C K.
Where is C? I was messed up with C C O N S T R E A I N T constraint from date time. Import that stuff. And then we have a is enrolled. This is going to be a boolean data type. However, we're going to go ahead and add a enrolled enrolled ecore date which is going to be having date as my which is going to be let's say um being which is going to be a dates data member that is going to be equal to mapped underscore column.
All right, I think that's about it, right? Control S, control arr C. I'm going to copy that. I'm going to grab FL here and then I'm going to go ahead and paste it.
Almost a clean sweep. You fixed all three things. I flag check constraint is back in the right import is enrolled is untouched as its own boolean column. And the new column uses map date as a proper date, proper type, not a hard-coded value. That's instinct check work. One small thing left. Look at the column name itself. Enrolled underscore date.
We agreed on enrollment date earlier in the session and it matches your raw SQL schema from the database module 2. Same table, same column name, same student, not a conceptual error, just a naming drift.
Okay. E N R O L M E N T L E N R O L L M E N T E N R O L L M N T.
There we go. And then I'm going to go ahead and let's take the rep plot out here. And then we're going to paste it.
Okay. And I think that was good. Okay, that's fully correct. I'm not going to read the whole thing. Let me save progress before we move on. Updating memory. All right, I guess I'm just going to wait patiently while the memor is being updated.
I wonder if I should have a gaming stream today because I don't really have class tomorrow.
Nope, I got an assignment today. I may have a gaming stream tomorrow to be honest. I got to have a workout stream as well. Oh my gosh. Okay, recall memory. Got the exact content. Retrying to edit the correct version. While the correct version is being edited, I'm going to go ahead and move on to my I don't know OBS to just see everything.
And let me know, do you guys like the new light? It's not a static scan light as opposed to that. It is a multicolor RGB light.
Yeah, it's sort of a multiolor. I got to change it today.
You go. I think I should do something about my camera, though. It's really high, so it feels like I'm literally busting my neck out here reading this stuff. Oh, wait. No, it's not. I was just I was just stalling for time here.
Okay, clean. That's a fully correct student class. Check constraint imported, right? Enrollment date as added as its own column with the proper date type. Nothing overwritten, nothing hardcoded. This one's done. There we go.
Progress save back to it. Chunk was almost closed out. One column less left email. And this one is very unique.
True. finally stops being theory and becomes real code. You write, you already told me last session correctly what unique equal true means. No two columns can share the same values. That does make sense and it is sort of uh liable for uh let's say email cuz no one can have the same email address, the same value in the comma. So the concept isn't new. What's new is just seeing it actually applied. Here's a twist. Before you write it though, go back to your raw SQL schema. Email variable chart 30 unique. Notice something. Email in your posgrsql table did not have no null on it. Puya and Devon both had null for email address. Only Marcus had a real value.
Prediction plain words. If email is if email is unique equal to true but allowed to be none but allowed to be null and you try to insert a second student with email equals to null. Priya already has null. You're now inserting Devon also with null. Does unique true constraint block that second null or let it through? It will uh let it through because null is not a value.
It basically means uh nothing and that we cannot lock something that is that does not exist.
There we go.
Let me get today's progress. Wow, that was that was done.
Oh, confirmed it. Reverted my earlier saved instinct. Okay. I I thought that claw just was like, "All right, it's so good that we're just going to save the progress here." Never mind.
Confirmed. It reverted. My earlier save didn't stick. Retrying now with the fresh version. Good. That's saved properly. Back to your answer. You said null gets two because it's not a value.
It means nothing. You can't block something that doesn't exist. That reasoning is actually correct. And here's the sharper version of why. So it's not so it's locked in for real and not just a lucky instinct.
Unique works by unique works by comparing values against each other. Is the same as is this the same as this?
Hello beta. Yo hiding bro. appreciate you joining the stream. Okay, but null doesn't represent a known value at all.
It represents unknown or absent. And here's the subtle part. In SQL's logic, null isn't even considered equal to another null. Two values can be confirmed to be duplicates of each other because neither of neither one has actual values to compare. So unique just doesn't apply. Multiple nulls are allowed though. Same as your raw SQL table already showed you with Puya and Devon. Okay. Correct. Same behavior carries over identically into SQL alchemies is unique equal to true. No surprises here. It inherits PostgresQL's own rule underneath it.
Nimu. What's that mean? Okay. Now write the email column. You you need mapped at index of string. You already know this type. mapped underscore column with unique equal to true applied for the first time in your code.
All right. Okay. This shouldn't be that hard. So apparently what I'm going to do is that I'm going to type email.
My email I'm going to use type in to specify the data type. My email is going to be of the string data type which is going to be equal to mapped column. I want to map it inside of my SQL's database where I want to go ahead and add a constraint to it. A column constraint that is going to be unique equals to false. Right?
I cannot allow unique unique equals to true. Surprise, no surprise here.
inherit equals to true which means unique equals to false is initially set to unique is initially set to false.
Oh no unique checks versus unique checks.
Perfect. That's exactly right. Map index of string unique true applied for real this time instead of just talked about no nullable false days yada yada. That's it. Chunk one declarative models is done. Every piece the OM concept itself base declarative base table map underscore column primary keys nullable unique check constraints and now all full six columns of student class matches your raw SQL's table.
All right.
Okay. That's locked properly. Chunk one is officially closed. Class dismissed.
Undeclarative model. Six columns. Three constraints. Two real analogies. Four fought through zero terminal violations.
The session. That's the strong of the day.
Huh. So, where do you want to go from your push into chunk two engine and connections engine and connecting right now or is it a good stopping point? Uh how many uh topics does the engine and connecting Oh god, are you kidding me? engine and connecting category have park system for the easier word.
I already save that content successfully in my last ride. Now the file okay so engine connecting a level yada yada what is the what the engine is the project that manages the actual connection of your postgrql database the connection string URL create engine so for topics noticeably lighter than chunk one okay and how many more categories are uh left for the SQL alchemy.
This is uh section question mark.
Okay, thanks for the flag. Let me confirm the file actually has one point completion yada yada confirmation. It reverted again. Still stuck at the old 60 days state. Resaving now. Wait, is my cloud's space full? Can my cloud not have any more memories? The hell? Thanks for the flag. updating.
Okay, it's not having it stop struggling to save. That's save now. Version CA7843348 C4 two reflects chunk one as complete chunk 2 engine session skirt relations migration. Oh wow, I don't feel like pushing but screw it.
Yeah, let's go.
All right. Okay, good. Chunk one's completion did save successfully on my retry. So, we're solid there. Let's move chunk two engine and connecting four topics. What the engine is the connection string create engine itself and connecting it to our modules to actually build the table. First topic, what the engine is? Quick check before I explain. Have you ever seen the term engine used it used in SQL alchemy context before even passing it?
Before even in passing? I have not.
Okay. And guys, my PC is actually blowing all the air in my freaking Vik away from it.
Confirmed.
It still reverted exactly like the no flag saving it now again.
Interesting dating memory. What? What is my memory full? How do you check it?
Dated yesterday. Updated two hours ago.
Okay, good. That's locked in for real well this time. Back to teaching. No prior exposure. Got it. Full explanation, no assumptions. Here's the picture. Think about everything you've built so far. Your students's class basemapped. All of that lives entirely inside Python.
It's just a description, a blueprint.
Right now, if you ran the file, nothing would actually touch at all.
No table gets created, no connections open, nothing happens on the database side. Your student class is just a shape sitting in the memory.
The engine is the piece that bridges that gap. It's the object that actually knows how to talk to your real Postgrql database. The login credentials, which host, which port, which specific database, think of it like this. Your student class is the blueprint for a house. The engine is the actual road truck and delivery crew that knows how to get a materials from blueprint to the real construction site. One critical thing to lock now before any micro conceptions can even form. Creating an engine does not immediately open a connection. It's more like the engine knows how to connect and where to connect, but it does not necessarily connect the second it's created. It connects lazily when it's actually needed. Quick isolator check. Single question, no code yet. True or false?
The moment you create an engine in your Python file, SQL Alchemy immediately opens a live connection to PostgreSQL database.
False.
Correct. False. And good. That's the right instinct locked in. Right. Get recall memory.
Are you kidding me? Is my stuff not saving?
Well, well, that feels This is the real storage issue on my end. Not something you need to worry about. I'm not going to keep burning our teaching time on repeated retries. I'll do one more.
consolidate and save covering everything through this point and if it doesn't stick I'll note it plainly in the transfer prompt and so nothing gets lost saved I'll keep an eye on whether it holds moving on oh wow guys later on I don't know I want to I'm so confused should I be a machine learning engineer like an AI engineer uh the reason I really went with AI engineer was because I thought it works with the AI's brain but now that I did some more research. I realized that machine learning engineers are who actually work on training the AIS's brain.
I really sort of want to be a machine learning engineer. I mean, I'm going to go over both. Let's see. I don't know.
That was a whole different change of topic when I said that stuff. After reading this part where it was like Claude's going to keep an eye whether it's going to save or not and that it does not want to burn through our teaching time. I'm like, damn, I want to create so many realistic AIs like this.
Okay, the condition string, the connection string, I mean this is address the engine uses to actually find and log into your database. The general shape looks like this. Postgrql username password at hostport/ data database_ame.
Let's map that directly on onto your actual setup. Since you've already got a posgrql 18 running with known details port 5432 super yada before I ask you to build the real thing quick isolated question no code in the URL shape what do you think host refers to given that your postgraphql server is running on your own local windows machine pixel appreciate you joining the stream okay before I ask you to build the real string Quick isolated question, no code. In that URL, clearly this URL, what do you think host refers to given that your Postgrql server is running on your own local Windows machine, not remote?
It refers to me.
That's the right intuition pointing in the right direction. You But let's get into the precise technical term because me isn't specific enough to actually put in a connection string. When something is running on your own machine, not some remote server out on the internet.
There's a standard term for this same uh computer. You've actually brushed up against this concept before. Even if the exact word hasn't come up yet, have you recall memory again? Confirm. Still stuck at the old snapshot. This is a persistent storage issue on my end tonight. Not something in your control.
I do not want you to keep spending I do not want to keep spending your teaching time on repeated retries. What?
Okay. Have you ever heard of local host before at any concept even out of database? You know what? Actually, I may I may work on this next stream. I cannot focus on the stuff now. Bro, did you uh check out FNAF lore yet? I actually did not. I did check out the Valerin lore, though.
Honestly, I may check it out later cuz I was thinking, do you guys think I should have a gaming stream right now? But I do have an assignment due by tonight. If I did not really have a gaming stream tonight, I may have it next stream to be honest. Don't ask the workout stream.
That is getting too stressful.
[clears throat] I probably should make workout videos first. Okay, you know what? Actually, I think I may call it a day here. I don't really want to uh stuff a lot of information to me right now cuz I can't clearly understand anything that Claude said here. So, I'm going to go ahead and move on to my main camera. There we go. And all right, guys. So, basically that was pretty much it for the stream. Uh I would have str for longer and all that stuff. Two reasons I did not. I don't want to completely run out of claws chat because I will be using it again. And secondly, I do not really want to overflood myself with all this uh new information.
Thirdly, I'm just kind of exhausted.
That said, if you guys did enjoy the stream, don't forget to smash that like button, subscribe with notifications turned on. And if you guys do enjoy my content, make sure to share my channel/ streams because liking helps my algorithm. Sharing makes you smile and subscribe like a chtop. That said, uh I haven't really worked on working with reream.io, but I will be sort of free this weekend. So, I will be working on learning how to be used reream.io. And once I did, I will be start I will start multi streaming as well. Therefore, if you guys don't enjoy my content and want to uh let's say follow me on my other socials, you guys can get access to all those social through the link in the description, through my bio or by typing exclamation in the socials with name on chat. all lower case, no space. If the social does exist, a link is going to pop up. If the social does not exist, the link will not pop up. That said, I did create two channels. One called well, I was going to say two brand new channels, but since it's been a month or two, it's not really brand new, but let's go with brand new. I did create two brand new channels beside this channel. One called Viv Arcade. The other called the Works Out. Viv Arcade is specifically meant for my gaming content. and the works out is specifically meant for my workout content. Therefore, if you guys are interested in either one of those genres or cate genres or categories and that you guys want to follow me there, you guys can get access to uh both those channels to my homepage. If you guys scroll all the way down, you guys will be seeing a featured channels category where I where I will be having those two channels featured out. That said, if you guys do want to follow me in my AI engineering for 365 days series and that you guys want access to the road map that I did use for this series or that I am currently using for this series, you guys can get access to it through my discord server. If you guys either go to the general chat, going helps with chat or python chat, mention my name there at Vivuniverse asking me for the road map.
I will be personally DMing it to you guys after the stream though, which is going to be ending in about I think a couple of minutes. That's it. Hi guys, you're hiding Calman here. Honestly, I think you came a little bit late. I am ending the stream right now, but I really don't want to, but I mean, I basically did the outro, but I may actually I'm going to work on my assignment right now. And if if I did have some time, I will be, let's say, having a gameplay or a gaming stream on my other channel. And maybe if I had a bit more time, I will be making a few workout videos and all that stuff. But for this stream, I'll catch you guys in live stream or video. Peace. Okay, I guess let's end the stream.
Related Videos

TOP 15 Data compression Interview Questions and Answers 2019 Part-2 | Data compression | Wisdom jobs
wisdomjobs
281 views•2019-06-28

CTS 158: 802.11w Management Frame Protection
ClearToSend
4K views•2019-02-04

NDSS 2019 Send Hardest Problems My Way: Probabilistic Path Prioritization for Hybrid Fuzzing
NDSSSymposium
496 views•2019-04-02

How realistic is Cities: Skylines?
CityBeautiful
159K views•2019-02-14

GUIs & TUIs: Choosing a User Interface for Your Python Project | Real Python Podcast
realpython
2K views•2025-04-04

The OSI Model - Explained by Example
hnasr
225K views•2019-05-12

Cloud Computing - Introduction
elithecomputerguy
98K views•2019-10-07

From Traveler's Dilemma to Dynamic Routing | Demystifying Networking
IITBombayJuly
5K views•2019-08-04
Trending

WOW! Judge TURNS THE TABLES on Trump in His OWN $10B LAWSUIT!!!
MeidasTouch
197K views•2026-07-23

Playstation NO DISC/NO BUY Fight Is Over...
DavidJaffeGames
4K views•2026-07-23

Steam and Xbox Just Dropped The Hammer On PlayStation
OhNoItsAlexx
9K views•2026-07-23

Americans Confused in Australia for 17 Minutes Straight
IWrocker
17K views•2026-07-23