forked from mikeckennedy/talk-python-transcripts
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy path005_mike_bayer_SQLAlchemy_and_data_access_in_Python.vtt
2861 lines (1907 loc) · 92.6 KB
/
005_mike_bayer_SQLAlchemy_and_data_access_in_Python.vtt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
WEBVTT
00:00:00.001 --> 00:00:07.960
Talk Python To Me, episode number five, with guest Mike Baer, recorded Thursday, April 9th, 2015.
00:00:07.960 --> 00:00:37.380
Hello and welcome to Talk Python to Me, a weekly podcast on Python,
00:00:37.380 --> 00:00:40.000
the language, the libraries, the ecosystem, and the personalities.
00:00:40.000 --> 00:00:41.600
This is your host, Michael Kennedy.
00:00:41.600 --> 00:00:45.000
Follow me on Twitter, where I'm @mkennedy,
00:00:45.000 --> 00:00:49.080
and keep up with the show and listen to past episodes at talkpythontome.com.
00:00:49.080 --> 00:00:53.260
This episode, we'll be talking with Mike Baer about SQLAlchemy.
00:00:53.260 --> 00:00:54.600
Let me introduce Mike.
00:00:54.600 --> 00:01:00.120
Mike Baer is the creator of several prominent Python libraries, including SQLAlchemy,
00:01:00.120 --> 00:01:04.760
Mako Templates for Python, Alembic Migrations, and Dogpile Caching.
00:01:04.940 --> 00:01:09.040
He's been working with open source software and databases since the mid-1990s.
00:01:09.040 --> 00:01:14.540
Today, he's active in the Python community, working to spread good software practices to an ever-wider audience.
00:01:14.540 --> 00:01:17.460
Mike is a semi-regular presenter at PyCon US,
00:01:17.460 --> 00:01:22.360
and has also spoken at many smaller events and conferences in the United States and Europe.
00:01:22.360 --> 00:01:24.540
Follow Mike on Twitter, where he's Zeke.
00:01:24.540 --> 00:01:27.240
That's at Z-Z-Z-E-E-K.
00:01:27.980 --> 00:01:28.900
Welcome to the show.
00:01:28.900 --> 00:01:30.800
Thanks. Thanks for having me.
00:01:30.800 --> 00:01:33.920
Yeah, I've been a longtime fan of SQLAlchemy.
00:01:33.920 --> 00:01:37.120
And, you know, when I started this podcast, I was thinking,
00:01:37.120 --> 00:01:38.700
who do I have to have on the show?
00:01:38.700 --> 00:01:39.940
And you were definitely on the list.
00:01:39.940 --> 00:01:41.040
That's very flattering.
00:01:41.040 --> 00:01:43.880
Yeah, you built some great stuff.
00:01:44.600 --> 00:01:49.600
So, before we get into the details of SQLAlchemy and how we should use it and why it's so awesome,
00:01:49.600 --> 00:01:53.280
maybe let's take a trip down memory lane, step back a little bit,
00:01:53.280 --> 00:01:55.620
and just, you know, how and when did you get into Python?
00:01:55.620 --> 00:02:00.920
I got into Python after kind of hesitating to get into it, meaning I knew about it,
00:02:00.920 --> 00:02:03.460
and it seemed like something that was appealing to me.
00:02:03.720 --> 00:02:06.980
But I kind of resisted mostly because of the white space thing.
00:02:06.980 --> 00:02:09.680
This is back in probably 2003.
00:02:09.680 --> 00:02:11.160
I was working at Major League Baseball.
00:02:11.160 --> 00:02:18.040
Most of my programming career before Python was doing a lot of Java and a lot of Perl.
00:02:18.040 --> 00:02:23.620
And I really liked the idea of object-oriented languages,
00:02:23.620 --> 00:02:25.360
and I liked the idea of scripting languages.
00:02:25.360 --> 00:02:28.280
So Java was very object-oriented.
00:02:28.280 --> 00:02:30.120
Perl was not too good at objects.
00:02:30.120 --> 00:02:32.500
But it was a scripting language.
00:02:32.500 --> 00:02:37.060
So I really wanted there to be some scripting language where I could write much cleaner code than you get in Perl.
00:02:37.060 --> 00:02:40.760
Yeah, so you kind of had half of what you wanted in one language.
00:02:40.760 --> 00:02:41.200
Yeah.
00:02:41.200 --> 00:02:43.500
But you wanted to bring it all together, right?
00:02:43.500 --> 00:02:45.380
And Python really looked like it.
00:02:45.380 --> 00:02:48.760
Python really looks like it, but it's got that stupid white space thing.
00:02:48.760 --> 00:02:50.380
And I just didn't want to get into it.
00:02:50.380 --> 00:02:53.020
And then one day when I was working at baseball,
00:02:53.020 --> 00:02:58.720
we were rolling out this client application called WinCVS, I think it was.
00:02:58.720 --> 00:03:00.320
It was a Windows CVS client.
00:03:00.600 --> 00:03:02.780
And we had to roll it out to people that were not programmers.
00:03:02.780 --> 00:03:10.160
And we needed to add hooks to it so that people could tag things and send things to different servers by tagging.
00:03:10.160 --> 00:03:12.920
And WinCVS's scripting language was Python.
00:03:13.600 --> 00:03:18.020
So I had to learn, you know, 10 lines of Python to do this script.
00:03:18.020 --> 00:03:21.620
And basically I spent like two hours with the white space thing.
00:03:21.620 --> 00:03:26.080
And I was like, oh, we do that white space anyway when the code is clean.
00:03:26.080 --> 00:03:27.940
And I'm actually totally fine with it.
00:03:27.940 --> 00:03:32.160
So let me just learn Python now that I've spent 10 minutes getting used to white space.
00:03:32.160 --> 00:03:36.520
That's really funny that it was like a real barrier to you, right?
00:03:36.520 --> 00:03:37.860
And then it just came down.
00:03:37.860 --> 00:03:40.920
It really bugged me because I was a really sloppy coder back then.
00:03:40.920 --> 00:03:43.560
Python really made me a much cleaner programmer.
00:03:43.560 --> 00:03:45.040
Yeah, that's a good point.
00:03:45.040 --> 00:03:46.180
I hadn't really thought about that.
00:03:46.180 --> 00:03:49.020
But it definitely does make you think about that.
00:03:49.020 --> 00:03:52.860
And, you know, a lot of the modern editors make it almost transparent to you.
00:03:52.860 --> 00:03:55.080
But I think there's the mental concept of it.
00:03:55.080 --> 00:03:56.280
And then there's the reality of it.
00:03:56.280 --> 00:03:58.660
And the reality is that it's actually not a big deal at all.
00:03:58.660 --> 00:03:59.400
It's super smooth.
00:03:59.400 --> 00:04:05.260
But when you're coming from, say, Java or C# or C++ or something, then it seems like a huge deal.
00:04:05.260 --> 00:04:08.360
Yeah, you get over it really quickly.
00:04:08.360 --> 00:04:09.080
Excellent.
00:04:09.080 --> 00:04:10.920
Oh, you bring up WinCVS.
00:04:10.920 --> 00:04:15.180
Boy, I used to use that thing back in the late 1990s or something.
00:04:15.180 --> 00:04:16.260
That brings back some memories.
00:04:16.260 --> 00:04:17.080
Yeah, that's kind of what it was, yeah.
00:04:17.080 --> 00:04:18.580
That's awesome.
00:04:18.580 --> 00:04:21.880
Let's talk about something more modern than WinCVS.
00:04:21.880 --> 00:04:23.020
Let's talk about SQLAlchemy.
00:04:23.020 --> 00:04:23.560
Sure.
00:04:23.920 --> 00:04:31.600
So can you just tell, I suspect that, you know, 90% of the listeners are fans of and familiar with SQLAlchemy.
00:04:31.600 --> 00:04:34.680
But there's going to be some folks who don't know or maybe they know it as a buzzword.
00:04:34.680 --> 00:04:37.020
Can you just tell everyone what SQLAlchemy is?
00:04:37.020 --> 00:04:41.860
So SQLAlchemy is this library that is, it's all about Python.
00:04:41.860 --> 00:04:47.580
And it's all about SQL and databases and interacting with databases.
00:04:47.580 --> 00:04:56.460
So it's basically when you need to work with a relational database, say you're going to work with like Postgres or MySQL, there's all kinds of things you need to do with the database.
00:04:56.460 --> 00:04:58.460
You need to write, you know, programs that talk to it.
00:04:58.460 --> 00:04:59.480
You need to get results back.
00:04:59.480 --> 00:05:01.280
You need to create schemas.
00:05:01.280 --> 00:05:04.560
You might need to be given some existing database and look at it.
00:05:05.420 --> 00:05:08.960
There's scripting and migrations of schemas you want to do.
00:05:08.960 --> 00:05:15.560
You probably are writing applications that have higher level business concepts that you want to map to that database.
00:05:15.560 --> 00:05:24.100
So SQLAlchemy started out with a really ambitious goal of having a place, a way to do that, a way to do all those things in Python.
00:05:24.100 --> 00:05:36.780
Not just being able to map like an object to a table, but all the features of managing schemas and creating schemas and reflecting them and working with SQL scripts and everything else.
00:05:36.780 --> 00:05:44.480
Working with data type problems, making all kinds of different database backends look as similar as is feasible.
00:05:44.480 --> 00:05:50.400
You know, like data types in Oracle are very weird compared to those in MySQL and SQLite's a whole different story.
00:05:51.340 --> 00:05:56.880
Those databases are always going to be different, but you can at least try to get some semblance of sanity across all of them.
00:05:56.880 --> 00:06:01.740
So that's why if you go to SQLAlchemy's website, the first thing it says is like the database toolkit for Python.
00:06:01.740 --> 00:06:02.820
It doesn't say it's an ORM.
00:06:02.820 --> 00:06:04.240
That's just one component.
00:06:04.240 --> 00:06:11.600
It's a toolkit that has kind of helpers for whatever you have to do with a database.
00:06:11.600 --> 00:06:13.040
SQLAlchemy can definitely have a role.
00:06:13.040 --> 00:06:13.920
That's excellent.
00:06:13.920 --> 00:06:20.940
You have at least two really nice sort of comprehensive walkthroughs, one for the core and one for the ORM component.
00:06:20.940 --> 00:06:23.700
That's SQLAlchemy.org, right?
00:06:23.700 --> 00:06:25.440
Yes, SQLAlchemy.org.
00:06:25.440 --> 00:06:30.320
So when did you get started with, when did you create SQLAlchemy and what inspired you to create it in the first place?
00:06:31.060 --> 00:06:39.580
So I was kind of writing the first iteration of SQLAlchemy in late 2005, and our first release was early 2006.
00:06:39.580 --> 00:06:45.100
And really when I was writing SQLAlchemy, it was not the first time I was creating a tool like that.
00:06:45.700 --> 00:06:55.280
When you work, or at least in the old days, when you used to work in the 90s in all these various internet shops, we had really little tools to work with.
00:06:55.280 --> 00:07:00.580
I mean, there were a lot of tools, but we were, you know, using Perl and libraries to talk databases were pretty crude.
00:07:01.300 --> 00:07:08.340
And I was using Java from day one when it was, you know, version 1.0, and there was literally no libraries before Hibernate.
00:07:08.340 --> 00:07:15.740
So throughout the 90s, you know, you get into the habit of writing little database access layers yourself.
00:07:15.740 --> 00:07:21.480
And every job you have, you're going to go and, now I'm going to write a really better database.
00:07:21.480 --> 00:07:23.900
You know, the database access layer I wrote last time sucked.
00:07:23.900 --> 00:07:24.980
Now I'm going to write a really good one.
00:07:25.320 --> 00:07:29.760
And you say that statement to yourself like five times, right?
00:07:29.760 --> 00:07:32.380
Yeah, every job you have, it's like, okay, this time we're going to get it right.
00:07:32.380 --> 00:07:36.040
We're going to write the ultimate, you know, set of tools, you know.
00:07:36.040 --> 00:07:42.540
And then as you're doing this, you know, as the 2000s rolled along, ORMs, you know, Hibernate suddenly was around.
00:07:42.540 --> 00:07:48.700
And I was doing a lot of Perl at MLB, and there were some ORM-ish things with Perl that looked terrible to me.
00:07:48.700 --> 00:07:49.520
They looked really simplistic.
00:07:51.180 --> 00:07:55.560
I had worked, by the time I was at MLB, I was working, that was, they were a big Oracle shop.
00:07:55.560 --> 00:07:58.700
I had already had a lot of gigs where I had worked a lot with Oracle.
00:07:58.700 --> 00:08:00.320
I had worked a lot with Postgres.
00:08:00.320 --> 00:08:03.500
I had worked a lot with Sybase, Microsoft SQL Server.
00:08:03.500 --> 00:08:10.380
I had worked a lot with not just MySQL, but its earlier MSQL incarnations in the early 90s.
00:08:10.780 --> 00:08:22.640
So I had, and I had written database code in Perl, Java, and C, C++, you know, because back in the early 90s, you know, we didn't, Perl wasn't always available for some cases.
00:08:23.300 --> 00:08:30.900
So I really had iterated a lot on this whole back and forth with the database, sending a SQL string, getting a result back, getting data back from the result.
00:08:30.900 --> 00:08:33.720
I knew a lot about that.
00:08:33.720 --> 00:08:40.020
So, and I always wanted to have a system that would be the last time I have to do this, you know.
00:08:40.020 --> 00:08:41.040
Yeah, I had that feeling.
00:08:41.040 --> 00:08:43.760
A long time, it was like, I was writing things in Java.
00:08:43.760 --> 00:08:49.340
I was going to write like a big toolkit in Java, like the big, you know, web framework, everything you need Java thing.
00:08:49.340 --> 00:08:50.220
And it never really happened.
00:08:50.220 --> 00:08:54.500
But eventually when I got into Python, that's when I really began doing it.
00:08:54.500 --> 00:08:58.660
I, you know, Python had kind of not a lot of libraries around.
00:08:58.660 --> 00:09:06.740
The only library that was feasible for database access on Python was SQL Object, which is a great library and was a huge influence on SQLAlchemy.
00:09:08.440 --> 00:09:14.560
And I started doing it and it was kind of based on the latest techniques I iterated at baseball.
00:09:14.560 --> 00:09:20.160
Like the idea is that if you want to talk to a database table, you make a data structure that represents what the table looks like.
00:09:20.160 --> 00:09:22.460
And we call that table metadata.
00:09:22.460 --> 00:09:28.200
But one critical thing I did with SQLAlchemy was I actually decided to read a book beforehand.
00:09:28.200 --> 00:09:32.220
So I had this book called Patterns of Enterprise Architecture by Martin Fowler.
00:09:32.220 --> 00:09:33.340
Yeah, that's a great book.
00:09:33.340 --> 00:09:38.120
And I read that book and half of the book was like, oh, that, oh, this, oh, this.
00:09:38.240 --> 00:09:39.340
All these things that I've done.
00:09:39.340 --> 00:09:40.720
And he kind of put names to them.
00:09:40.720 --> 00:09:46.060
And then as he did all that, there were some other patterns that I was not familiar with, like the unit of work pattern.
00:09:46.060 --> 00:09:46.960
I was like, wow, look at that.
00:09:46.960 --> 00:09:47.580
I've never heard of that.
00:09:47.580 --> 00:09:48.180
That's pretty cool.
00:09:48.180 --> 00:09:51.540
And does that appear as the session in SQLAlchemy now?
00:09:51.540 --> 00:09:52.160
Yeah, the session.
00:09:52.160 --> 00:09:52.380
Yeah.
00:09:52.380 --> 00:09:54.140
And actually session is from Hibernate.
00:09:54.140 --> 00:09:55.240
Hibernate's got the same thing.
00:09:55.820 --> 00:09:58.600
So I, you know, really made a go at it.
00:09:58.600 --> 00:10:02.840
And I said, I'm actually going to read a book beforehand and really try to get all these patterns right.
00:10:02.840 --> 00:10:05.220
And that's kind of how it started.
00:10:05.220 --> 00:10:09.140
And it took a very long time for SQLAlchemy to be any good.
00:10:09.220 --> 00:10:15.860
I mean, I think when I first released it, it had a lot of the special things going on that made people like it.
00:10:15.860 --> 00:10:17.660
But it was not executed very well.
00:10:17.660 --> 00:10:22.180
But, you know, over the years, over really 10 years, it's gotten very refined.
00:10:22.180 --> 00:10:23.080
But it's taken a long time.
00:10:23.500 --> 00:10:24.800
Yeah, it's quite a mature product.
00:10:24.800 --> 00:10:25.700
And that's cool.
00:10:25.700 --> 00:10:26.340
Yeah.
00:10:26.340 --> 00:10:29.420
Did you use it internally before you actually released it?
00:10:29.420 --> 00:10:31.500
Or was it kind of, I'm building it out in public?
00:10:31.500 --> 00:10:33.180
Yeah, no, it was funny.
00:10:33.180 --> 00:10:35.340
When I was starting in Python, I was writing open source.
00:10:35.340 --> 00:10:42.780
The first thing I wrote was this template language called Mighty, which was basically almost a line for line port of a template thing in Perl called HTML Mason.
00:10:42.780 --> 00:10:45.640
That was the first open source thing I published.
00:10:45.640 --> 00:10:48.820
And then Mighty was kind of an embarrassment eventually.
00:10:48.820 --> 00:10:50.400
And I wrote Mako to replace it.
00:10:50.800 --> 00:10:55.480
But I was writing these libraries at first without having any job.
00:10:55.480 --> 00:10:57.920
The gigs I was doing were still Java jobs.
00:10:57.920 --> 00:11:00.880
I was still doing, after I left baseball, I was still doing Java work.
00:11:00.880 --> 00:11:06.820
Python was certainly used in the mid-2000s, but it was not as dominant as it is today.
00:11:06.820 --> 00:11:11.960
I didn't actually get to use SQLAlchemy for a real gig until version 0.5.
00:11:11.960 --> 00:11:17.620
So maybe four years into it, I finally was on a gig where like, hey, we can do this thing in Python and we can do this.
00:11:17.620 --> 00:11:20.060
And everyone was like, okay, use the Python thing.
00:11:20.620 --> 00:11:22.200
Yeah, use that toy language.
00:11:22.200 --> 00:11:22.880
Yeah, yeah, yeah.
00:11:22.880 --> 00:11:24.200
It was kind of like that, yeah.
00:11:24.200 --> 00:11:28.120
And it was actually the website for a TV show called Charlie Rose, which is on PBS.
00:11:28.120 --> 00:11:28.720
Oh, yeah, yeah.
00:11:28.720 --> 00:11:29.020
Great.
00:11:29.020 --> 00:11:37.740
Yeah, we wrote, I don't know if it's still up in that incarnation anymore, but at the time, this is maybe 2007, it was written using early version of pylons.
00:11:38.300 --> 00:11:40.740
And that was the first time I used SQLAlchemy on the job myself.
00:11:40.740 --> 00:11:45.620
And SQLAlchemy improved by leaps and bounds on that gig because I had like, oh, this sucks.
00:11:45.620 --> 00:11:46.480
Oh, look at this thing.
00:11:46.480 --> 00:11:47.120
This thing is terrible.
00:11:47.120 --> 00:11:49.060
How could people have been using this for three years?
00:11:49.060 --> 00:11:50.120
Yeah, that's excellent.
00:11:50.880 --> 00:11:51.380
Yeah.
00:11:51.380 --> 00:11:52.960
So it's weird.
00:11:52.960 --> 00:11:53.540
Yeah.
00:11:53.540 --> 00:11:55.460
It was written kind of in a vacuum.
00:11:55.460 --> 00:11:58.520
Like I only knew what my users told me for several years.
00:11:58.940 --> 00:11:59.960
Yeah, very cool.
00:11:59.960 --> 00:12:06.620
The previous show that's not out yet, but was recorded just before this is a guy named Mahmoud Hashemi from eBay PayPal.
00:12:06.620 --> 00:12:12.520
And the whole show is about sort of enterprise Python and sort of using it as a real proper language.
00:12:12.520 --> 00:12:15.940
And I think, you know, it's probably that time frame and that era.
00:12:15.940 --> 00:12:23.800
There's a lot of similar ideas about, hey, we could actually build real websites and, you know, web scale professional apps with this language.
00:12:23.800 --> 00:12:24.240
It's great.
00:12:24.240 --> 00:12:24.880
Yeah.
00:12:24.880 --> 00:12:25.480
Yeah.
00:12:25.540 --> 00:12:33.180
I mean, Python as enterprise was something that I think, you know, it existed in the early 2000s.
00:12:33.180 --> 00:12:40.200
Like I think a lot of people were using, I mean, people were using like Zope or Plone, I think was the early, you know, incarnation of enterprise Python.
00:12:40.200 --> 00:12:48.540
But I think, you know, really you got to hand it to like, I mean, first Ruby on Rails got people more comfortable with scripting languages for enterprise.
00:12:48.540 --> 00:12:51.280
And then Django really helped a lot too.
00:12:51.280 --> 00:12:53.360
Django really brought a lot of people to Python.
00:12:54.200 --> 00:13:02.080
And I think the critical mass kind of started happening for Python kind of in 2005 on forward.
00:13:02.080 --> 00:13:03.440
Absolutely.
00:13:03.440 --> 00:13:14.380
And I think, you know, to shoot your horn and everybody else's a little bit, the stuff that's in PyPy, all those packages out there make it really hard to not consider Python.
00:13:14.380 --> 00:13:19.360
The fact that you can just pip install magic, you know, and build stuff so quickly.
00:13:19.360 --> 00:13:21.500
Like, why would I start from scratch, you know?
00:13:21.500 --> 00:13:21.780
Right.
00:13:21.780 --> 00:13:22.220
Absolutely.
00:13:22.840 --> 00:13:24.940
We now know what SQLAlchemy is, if we didn't.
00:13:24.940 --> 00:13:28.920
Can you kind of give us like a, I know it's hard to talk about code, so don't get too detailed.
00:13:28.920 --> 00:13:32.880
But can you give me a little walkthrough of like what is involved in getting started?
00:13:32.880 --> 00:13:37.280
Like what do I do in code to maybe make a basic query or connect to the database?
00:13:37.800 --> 00:13:40.760
So there's different ways that you might want to use the system.
00:13:40.760 --> 00:13:43.880
I mean, there's the level, the layer of I want to just make a query.
00:13:43.880 --> 00:13:45.320
And that's pretty easy.
00:13:45.320 --> 00:13:49.020
I mean, SQLAlchemy has a lot of different levels that it can be used at.
00:13:49.020 --> 00:13:52.300
Like if you want to just connect to a database and make a query, that's like a really two line.
00:13:52.420 --> 00:13:57.260
You make an object called an engine, which you give it a URL for a database.
00:13:57.260 --> 00:14:01.460
And then the engine can just accept queries as strings directly.
00:14:01.460 --> 00:14:08.480
And right there, you've already saved maybe 10 lines of code versus what it would be with the raw Python database.
00:14:08.480 --> 00:14:09.540
Yeah, that's fantastic.
00:14:09.540 --> 00:14:11.800
Maybe we should take a step back and talk about the layers.
00:14:11.800 --> 00:14:15.180
And then we could talk about, you know, well, this layer, that layer, it looks like such and such.
00:14:15.180 --> 00:14:17.220
So you have the core and you have the ORM.
00:14:17.220 --> 00:14:19.220
Can you talk about that a little?
00:14:19.400 --> 00:14:25.320
Yeah, so I actually wrote SQLAlchemy in this inside-out way where I didn't even worry about the –
00:14:25.320 --> 00:14:28.420
I mean, I kind of knew what I wanted to do for the ORM, but I didn't even worry about that for a few months.
00:14:28.420 --> 00:14:34.860
I wrote first just the engine, just like the concept of here's how to connect to a database using the Python DB API.
00:14:34.860 --> 00:14:44.020
And here's a way that we can execute a query and get results back in a way that's a little bit nicer than what the raw Python database API gives you.
00:14:44.020 --> 00:14:46.660
It's a little bit nicer and a little more consistent.
00:14:47.160 --> 00:14:54.500
Then the next thing I did, which, you know, was soon after, was I wrote the table metadata system, which I had already done many times at different jobs.
00:14:54.500 --> 00:14:56.940
You know, kind of looked in Fowler's book.
00:14:56.940 --> 00:15:06.260
So you wrote – you create this concept of a Python data structure that mirrors what structures you have in your database.
00:15:06.400 --> 00:15:12.380
So when you have a relational database, it kind of – without using it at all, it has a fixed schema.
00:15:12.380 --> 00:15:17.400
You have, like, tables that are kind of – they're not – we might call them physical tables, which they're really not physical.
00:15:17.400 --> 00:15:18.340
They're just on a disk.
00:15:18.340 --> 00:15:23.280
But they're tables, and the tables have columns, and they're kind of like the things that are going to store your data.
00:15:24.280 --> 00:15:35.760
So you model a mirror of all that stuff in Python so that you can write Python code that refers to this object structure that can then relate directly to how the database is built.
00:15:36.000 --> 00:15:38.020
So that's called database metadata.
00:15:38.020 --> 00:15:41.620
So it means it's information about the structure of your database.
00:15:42.380 --> 00:15:52.960
Then from that, the table metadata objects in SQLAlchemy have all these methods on them, like select and update and, you know, table.select.where.
00:15:52.960 --> 00:15:58.940
And when I say, you know, x.y.z, the dot in Python means that we're calling a method on an object.
00:15:58.940 --> 00:16:05.400
And if you have this pattern where you say an object.call this, and then you get something back, and then you say .call that,
00:16:05.800 --> 00:16:13.180
that's a pattern called method chaining, which means that you keep calling methods on this object that keeps returning a new copy of itself.
00:16:13.180 --> 00:16:20.700
So that's a common pattern used in database query libraries because the method chaining is kind of like you're building up this data structure
00:16:20.700 --> 00:16:23.100
that looks like basically a syntax tree.
00:16:23.100 --> 00:16:31.300
A syntax tree basically represents like some code, but it represents the code as a set of objects connected together in a tree.
00:16:31.300 --> 00:16:32.260
Yeah, that's fantastic.
00:16:32.260 --> 00:16:37.820
I really like the fluent API that you put together there where basically you start with a query, and whatever you do to it,
00:16:37.820 --> 00:16:40.040
what comes out of the query and just lets you build up.
00:16:40.040 --> 00:16:41.840
Here's a where clause.
00:16:41.840 --> 00:16:42.600
Here's an order by.
00:16:42.600 --> 00:16:44.300
Here's a distinct or whatever.
00:16:44.300 --> 00:16:44.900
Yeah.
00:16:44.900 --> 00:16:48.340
At this point, I mean, that pattern is pretty commonplace these days.
00:16:48.340 --> 00:16:50.560
I mean, when I first did it, it was not quite as commonplace.
00:16:50.560 --> 00:16:58.100
I mean, basically Java Hibernate kind of has that pattern, but not in a nice way because Java is just not as slick of a language as Python.
00:16:58.100 --> 00:17:01.540
And some of the, you know, it was a pattern that was around.
00:17:01.540 --> 00:17:03.500
I think SQL object had it as well, you know.
00:17:03.500 --> 00:17:07.100
It builds on that, but then we also did this thing.
00:17:07.100 --> 00:17:16.140
I took this thing right from Ian Bicking's SQL object, which was that you overload Python operators like the double equals operator or the greater than operator,
00:17:16.140 --> 00:17:25.040
so that when you have these little objects that refer to columns and values in a database, you can compare them with the Python comparison operators,
00:17:25.160 --> 00:17:29.860
and they kind of auto-magically create another object like a comparison.
00:17:30.860 --> 00:17:41.060
And if you go through the ORM or the core tutorial on SQL object, the core tutorial would really show how this works at the expression level.
00:17:41.060 --> 00:17:46.000
The ORM tutorial kind of refers to it, but it's more about how to get the ORM going.
00:17:46.420 --> 00:17:48.960
But what I'm talking about here is how the core query system works.
00:17:48.960 --> 00:17:55.560
So basically these Python objects can kind of expressly be combined to create SQL queries.
00:17:56.460 --> 00:17:57.820
And that's the core, really.
00:17:57.820 --> 00:18:02.840
That's really what you get, as well as the fact that it returns objects, it returns Python objects.
00:18:02.840 --> 00:18:06.480
Like if you query for dates, you'll get a Python date object back.
00:18:06.480 --> 00:18:09.700
If you query for intervals, you can get a Python time delta back.
00:18:09.700 --> 00:18:14.720
And there's all systems for building your own custom types if you want to get JSON back, things like that.
00:18:15.300 --> 00:18:17.260
And then the ORM builds on top of that.
00:18:17.260 --> 00:18:22.540
So if you're starting out, I mean, if you really want to learn the library from the ground up, I would start with the core and then move to the ORM.
00:18:22.540 --> 00:18:29.880
If you want to get some quick results for a program you're writing, you might want to start with the ORM first and then do a deeper dive later.
00:18:29.880 --> 00:18:34.920
I've kind of switched those directions around over the years, and I think there's just two ways to learn.
00:18:34.920 --> 00:18:37.220
You can learn from the outside in or learn from the inside out.
00:18:37.800 --> 00:18:45.380
And it's kind of your choice as to do you want immediate gratification or do you want more fundamental knowledge first?
00:18:45.380 --> 00:18:45.800
Right.
00:18:45.800 --> 00:18:48.540
Well, and how much are you going to be depending on the library?
00:18:48.540 --> 00:18:50.020
Right.
00:18:50.020 --> 00:18:55.540
If it's your core business app and it's really important that this thing keeps working, maybe you should deeply understand it.
00:18:55.540 --> 00:18:59.720
If it's just a little blog you're throwing together, do it quick and then come back and learn it more deeply.
00:18:59.720 --> 00:18:59.980
Right.
00:18:59.980 --> 00:19:02.060
Start with the ORM and then go to the core to understand that.
00:19:02.060 --> 00:19:02.400
Yeah.
00:19:02.400 --> 00:19:05.040
Well, everyone I've seen, everyone's got a different way to do it.
00:19:05.040 --> 00:19:06.660
So I just try to present both.
00:19:07.440 --> 00:19:11.920
And also for a really long time, the core didn't have that name core, and that was a problem.
00:19:11.920 --> 00:19:17.300
It was just called SQLAlchemy, and then there was SQLAlchemy ORM, and people didn't really, you know, obviously understand.
00:19:17.300 --> 00:19:20.280
There's this whole thing with SQLAlchemy that is not the ORM.
00:19:20.280 --> 00:19:27.360
So I introduced the word core probably about, you know, five years ago to say, hey, there's this whole other thing.
00:19:27.360 --> 00:19:33.780
And I divided the docs into like two big left and right sections so that you can see there's this whole other thing.
00:19:33.780 --> 00:19:37.400
There's only the core, and it's like an entire set, the right half of the docs.
00:19:37.820 --> 00:19:38.100
Yeah.
00:19:38.100 --> 00:19:40.480
I think you have them almost as columns next to each other.
00:19:40.480 --> 00:19:40.620
I do.
00:19:40.620 --> 00:19:41.660
I kind of imitated.
00:19:41.660 --> 00:19:45.680
I think Django's documentation at the time had that thing going on with the two columns.
00:19:45.680 --> 00:19:48.380
So I did that to say like, look, this is whole core thing.
00:19:48.380 --> 00:19:52.340
If you don't like the ORM, because I knew the ORM was going to be, the ORM is more opinionated.
00:19:52.340 --> 00:19:54.460
I knew it would be controversial.
00:19:54.960 --> 00:19:57.160
I knew that I personally didn't like ORMs very much.
00:19:57.160 --> 00:19:59.580
And this was going to be the ORM that I was actually going to like.
00:19:59.580 --> 00:20:02.000
But I knew all the other commercials like me were going to hate it.
00:20:02.000 --> 00:20:04.320
And those people still around today who hate ORMs.
00:20:04.320 --> 00:20:06.620
So I wanted to say like, look, I get it.
00:20:06.620 --> 00:20:07.620
Don't use the ORM.
00:20:07.620 --> 00:20:08.640
Use the core part.
00:20:08.720 --> 00:20:12.620
And then when you kind of use it for a long time, you realize, hey, this redundant thing
00:20:12.620 --> 00:20:14.920
I'm doing over and over again could just kind of be automated by the ORM.
00:20:14.920 --> 00:20:17.820
Then you can use the ORM when you see there's a need for it.
00:20:17.820 --> 00:20:19.880
So that's kind of how I saw it being used.
00:20:19.880 --> 00:20:21.120
But other people go the other way.
00:20:21.120 --> 00:20:21.780
Sure.
00:20:21.940 --> 00:20:26.360
So you've sort of talked about the learning perspective of when I might use the core versus
00:20:26.360 --> 00:20:26.840
the ORM.
00:20:26.840 --> 00:20:29.720
But are there like performance or other patterns?
00:20:29.720 --> 00:20:33.380
Like what other considerations do I choose between the core and the ORM model?
00:20:33.380 --> 00:20:35.260
There's a lot of performance.
00:20:35.260 --> 00:20:36.300
There's a lot of, yeah.
00:20:36.300 --> 00:20:42.040
So kind of the unspoken drama of SQLogamy for all the years it's been out has been the performance