Skip to content

Commit 126af05

Browse files
committed
rebase
2 parents 9ce41a4 + 84eae8c commit 126af05

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+770
-172
lines changed

CONTRIBUTING.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,5 @@ Note: make changes to the source/content/pages/\*.rst files then execute a
6262

6363
2. Sync your repo with the original repo::
6464

65-
$ git checkout master
6665
$ git fetch upstream
67-
$ git merge upstream/master
66+
$ git merge upstream/gh-pages

about-author.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ <h3 class="panel-head"><a href="/table-of-contents.html" style="color: #fff;">Ta
125125
<a href="/data.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Data</a>
126126
<a href="/databases.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Databases</a>
127127
<a href="/no-sql-datastore.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>NoSQL Data Stores</a>
128-
<a href="/object-relational-mappers-orms.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Object-relational Mappers</a>
128+
<a href="/object-relational-mappers-orms.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Object-relational Mappers (ORMs)</a>
129129
<a href="/application-programming-interfaces.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Application Programming Interfaces</a>
130130
<a href="/api-integration.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>API Integration</a>
131131
<a href="/api-creation.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>API Creation</a>

all.html

Lines changed: 175 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,15 +3101,21 @@ <h3>Key-value pair data stores</h3>
31013101
</ul>
31023102
<h3>Key-value pair resources</h3>
31033103
<ul>
3104-
<li>
3105-
<p><a href="http://dba.stackexchange.com/questions/607/what-is-a-key-value-store-database">What is a key-value store database?</a>
3106-
is a Stack Overflow Q&amp;A that straight on answers this subject.</p>
3107-
</li>
3104+
<li><a href="http://dba.stackexchange.com/questions/607/what-is-a-key-value-store-database">What is a key-value store database?</a>
3105+
is a Stack Overflow Q&amp;A that straight on answers this subject.</li>
3106+
</ul>
3107+
<h3>Redis resources</h3>
3108+
<ul>
31083109
<li>
31093110
<p>"<a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-redis">How To Install and Use Redis</a>"
31103111
is a guide for getting up with the extremely useful in-memory data store.</p>
31113112
</li>
31123113
<li>
3114+
<p><a href="http://degizmo.com/2010/03/22/getting-started-redis-and-python/">Getting started with Redis and Python</a>
3115+
is a walkthrough for installing and playing around with the basics of
3116+
Redis.</p>
3117+
</li>
3118+
<li>
31133119
<p>This video on
31143120
<a href="https://www.youtube.com/watch?v=rP9EKvWt0zo">Scaling Redis at Twitter</a> is
31153121
a detailed look behind the scenes with a massive Redis deployment.</p>
@@ -3275,34 +3281,118 @@ <h1>Object-relational mappers (ORMs)</h1>
32753281
<h2>Why are ORMs useful?</h2>
32763282
<p>ORMs provide a high-level abstraction upon a
32773283
<a href="/databases.html">relational database</a> that allows a developer to write
3278-
Python code instead of SQL to create, read, update and delete data in
3279-
their database. Developers can use the programming language they are
3280-
comfortable with, in our case Python, to work with data and not have to
3281-
write SQL statements or stored procedures.</p>
3282-
<p>However, Python ORM libraries are not required for accessing relational
3283-
databases. In fact, the low-level access is typically provided by another
3284-
library, such as <a href="http://initd.org/psycopg/">psycopg</a> (for PostgreSQL)
3285-
or <a href="https://pypi.python.org/pypi/MySQL-python/1.2.5">MySQL-python</a> (for
3286-
MySQL).</p>
3287-
<p>Developers can also use ORMs without a web framework, such as when
3288-
creating a data analysis tool or a batch script without a user interface.</p>
3284+
Python code instead of SQL to create, read, update and delete data and
3285+
schemas in their database. Developers can use the programming language they
3286+
are comfortable with to work with a database instead of writing SQL
3287+
statements or stored procedures.</p>
3288+
<p>For example, without an ORM a developer would write the following SQL
3289+
statement to retrieve every row in the USERS table where the
3290+
<code>zip_code</code> column is 94107:</p>
3291+
<div class="highlight"><pre>SELECT * FROM USERS WHERE zip_code=94107;
3292+
</pre></div>
3293+
3294+
3295+
<p>The equivalent Django ORM query would instead look like the following Python
3296+
code:</p>
3297+
<div class="highlight"><pre># obtain everyone in the 94107 zip code and assign to users variable
3298+
users = Users.objects.filter(zip_code=94107)
3299+
</pre></div>
3300+
3301+
3302+
<p>The ability to write Python code instead of SQL can speed up web application
3303+
development, especially at the beginning of a project. The potential
3304+
development speed boost comes from not having to switch from Python code
3305+
into writing declarative paradigm SQL statements. While some software
3306+
developers may not mind switching back and forth between languages, it's
3307+
typically easier to knock out a prototype or start a web application using
3308+
a single programming language.</p>
3309+
<p>ORMs also make it theoretically possible to switch an application between
3310+
various relational databases. For example, a developer could use SQLite for
3311+
local development and MySQL in production. A production application could
3312+
be switched from MySQL to PostgreSQL with minimal code modifications.</p>
3313+
<p>In reality however, it's best to use the same database for local development
3314+
as is used in production. Otherwise unexpected errors could hit in production
3315+
that were not seen in a local development environment. Also, it's rare that
3316+
a project would switch from one database in production to another one unless
3317+
there was a pressing reason.</p>
32893318
<div class="well see-also">
32903319
While you're learning about ORMs you should also read up on
32913320
<a href="/deployment.html">deployment</a> and check out the
32923321
<a href="/application-dependencies.html">application dependencies</a> page.
32933322
</div>
32943323

3324+
<h2>Do I have to use an ORM for my web application?</h2>
3325+
<p>Python ORM libraries are not required for accessing relational
3326+
databases. In fact, the low-level access is typically provided by another
3327+
library called a <em>database connector</em>, such as
3328+
<a href="http://initd.org/psycopg/">psycopg</a> (for PostgreSQL)
3329+
or <a href="https://pypi.python.org/pypi/MySQL-python/1.2.5">MySQL-python</a> (for
3330+
MySQL). Take a look at the table below which shows how ORMs can work with
3331+
different web frameworks and connectors and relational databases.</p>
3332+
<p><img src="theme/img/orm-examples.png" width="100%" alt="Examples of how varying Python ORMs can work with different connectors and backends." class="technical-diagram" /></p>
3333+
<p>The above table shows for example that SQLAlchemy can work with varying
3334+
web frameworks and database connectors. Developers can also use ORMs without
3335+
a web framework, such as when creating a data analysis tool or a batch
3336+
script without a user interface.</p>
32953337
<h2>What are the downsides of using an ORM?</h2>
32963338
<p>There are numerous downsides of ORMs, including</p>
32973339
<ol>
3298-
<li>impedance mismatch</li>
3299-
<li>difficulty writing complex queries</li>
3300-
<li>potential for reduced performance</li>
3301-
<li>shifting complexity into the application from the database layer</li>
3340+
<li>Impedance mismatch</li>
3341+
<li>Potential for reduced performance</li>
3342+
<li>Shifting complexity from the database into the application code</li>
33023343
</ol>
3303-
<h2>Django's ORM</h2>
3304-
<p>The <a href="/django.html">Django</a> web framework comes with its own built-in
3305-
object-relational mapping module, generally referred to as "the Django ORM".</p>
3344+
<h3>Impedance mismatch</h3>
3345+
<p>The phrase "impedance mismatch" is commonly used in conjunction with ORMs.
3346+
Impedance mismatch is a catch-all term for the difficulties that occur when
3347+
moving data between relational tables and application objects. The gist
3348+
is that the way a developer uses objects is different from how data is
3349+
stored and joined in relational tables.</p>
3350+
<p><a href="http://www.agiledata.org/essays/impedanceMismatch.html">This article on ORM impedance mismatch</a>
3351+
does a solid job of explaing what the concept is at a high level and
3352+
provides diagrams to visualize why the problem occurs.</p>
3353+
<h3>Potential for reduced performance</h3>
3354+
<p>One of the concerns that's associated with any higher-level abstraction or
3355+
framework is potential for reduced performance. With ORMs, the performance
3356+
hit comes from the translation of application code into a corresponding SQL
3357+
statement which may not be tuned properly.</p>
3358+
<p>ORMs are also often easy to try but difficult to master. For example, a
3359+
beginner using Django might not know about the
3360+
<a href="https://docs.djangoproject.com/en/1.8/ref/models/querysets/#select-related"><code>select_related()</code> function</a>
3361+
and how it can improve some queries' foreign key relationship performance.
3362+
There are dozens of performance tips and tricks for every ORM. It's possible
3363+
that investing time in learning those quirks may be better spent just
3364+
learning SQL and how to write stored procedures.</p>
3365+
<p>There's a lot of hand-waving "may or may not" and "potential for" in this
3366+
section. In large projects ORMs are good enough for roughly 80-90% of use
3367+
cases but in 10-20% of a project's database interactions there can be
3368+
major performance improvements by having a knowledgeable database
3369+
adminstrator write tuned SQL statements to replace the ORM's generated
3370+
SQL code.</p>
3371+
<h3>Shifting complexity from the database into the app code</h3>
3372+
<p>The code for working with an application's data has to live somewhere. Before
3373+
ORMs were common, database stored procedures were used to encapsulate the
3374+
database logic. With an ORM, the data manipulation code instead lives within
3375+
the application's Python codebase. The addition of data handling logic in the
3376+
codebase generally isn't an issue with a sound application design, but it does
3377+
increase the total amount of Python code instead of splitting code between
3378+
the application and the database stored procedures.</p>
3379+
<h2>Python ORM Implementations</h2>
3380+
<p>There are numerous ORM implementations written in Python, including</p>
3381+
<ol>
3382+
<li><a href="https://docs.djangoproject.com/en/1.8/topics/db/">The Django ORM</a></li>
3383+
<li><a href="http://www.sqlalchemy.org/">SQLAlchemy</a></li>
3384+
<li><a href="https://peewee.readthedocs.org/en/latest/">Peewee</a></li>
3385+
<li><a href="http://ponyorm.com/">PonyORM</a></li>
3386+
<li><a href="http://sqlobject.org/">SQLObject</a></li>
3387+
</ol>
3388+
<p>There are other ORMs, such as Canonical's
3389+
<a href="https://storm.canonical.com/">Storm</a>, but most of them do not appear to
3390+
currently be under active development. Learn more about the major active
3391+
ORMs below.</p>
3392+
<h3>Django's ORM</h3>
3393+
<p>The <a href="/django.html">Django</a> web framework comes with
3394+
its own built-in object-relational mapping module, generally referred to
3395+
as "the Django ORM" or "Django's ORM".</p>
33063396
<p><a href="https://docs.djangoproject.com/en/dev/topics/db/">Django's ORM</a> works well
33073397
for simple and medium-complexity database operations. However, there are often
33083398
complaints that the ORM makes complex queries much more complicated than
@@ -3312,25 +3402,36 @@ <h2>Django's ORM</h2>
33123402
replacing the default ORM with SQLAlchemy is currently a hack workaround. Note
33133403
though that some of the Django core committers believe it is only a matter of
33143404
time before the default ORM is replaced with SQLAlchemy. It will be a large
3315-
effort to get that working though so it's likely to come in Django 1.9 or
3316-
later.</p>
3405+
effort to get that working though so it's likely to come in
3406+
<a href="https://github.com/makaimc/fullstackpython.com/issues/48">Django 1.9 or later</a>.</p>
33173407
<p>Since the majority of Django projects are tied to the default ORM, it's best to
33183408
read up on advanced use cases and tools for doing your best work within the
33193409
existing framework.</p>
3320-
<h2>SQLAlchemy</h2>
3321-
<p><a href="http://www.sqlalchemy.org/">SQLAlchemy</a> is currently the most respected
3322-
Python ORM because it typically get the abstraction level "just right" and
3323-
seems to make complex database queries easier to write than the Django ORM
3324-
in most cases. SQLAlchemy is typically used with Flask as the database ORM
3325-
via the <a href="https://pythonhosted.org/Flask-SQLAlchemy/">Flask-SQLAlchemy</a>
3410+
<h3>SQLAlchemy</h3>
3411+
<p><a href="http://www.sqlalchemy.org/">SQLAlchemy</a> is a well-regarded
3412+
Python ORM because it gets the abstraction level "just right" and
3413+
seems to make complex database queries easier to write than the Django
3414+
ORM in most cases. SQLAlchemy is typically used with Flask as the database
3415+
ORM via the <a href="https://pythonhosted.org/Flask-SQLAlchemy/">Flask-SQLAlchemy</a>
33263416
extension.</p>
3327-
<h2>Peewee</h2>
3328-
<p><a href="https://peewee.readthedocs.org/en/latest/">Peewee</a> is another Python ORM
3417+
<h3>Peewee</h3>
3418+
<p><a href="https://peewee.readthedocs.org/en/latest/">Peewee</a> is a Python ORM
33293419
written to be
3330-
<a href="http://charlesleifer.com/blog/the-case-for-peewee-small-hackable-and-fun/">simpler, smaller and more hackable</a>
3420+
"<a href="http://charlesleifer.com/blog/the-case-for-peewee-small-hackable-and-fun/">simpler, smaller and more hackable</a>"
33313421
than SQLAlchemy. The analogy used by the core Peewee author is that Peewee
33323422
is to SQLAlchemy as SQLite is to PostgreSQL. An ORM does not have to work
33333423
for every exhaustive use case in order to be useful.</p>
3424+
<h3>Pony</h3>
3425+
<p><a href="http://ponyorm.com/">Pony ORM</a> is another Python ORM with a slight twist in
3426+
its licensing model. The project is multi-licensed. Pony is free for use
3427+
on open source projects but has a
3428+
<a href="http://ponyorm.com/license-and-pricing.html">commercial license</a> that
3429+
is required for commercial projects. The license is a one-time payment
3430+
and does not necessitate a recurring fee.</p>
3431+
<h3>SQLObject</h3>
3432+
<p><a href="http://sqlobject.org/">SQLObject</a> is an ORM that has been under active
3433+
open source development since
3434+
<a href="http://sqlobject.org/News1.html#sqlobject-0-5">before 2003</a>.</p>
33343435
<h2>Schema migrations</h2>
33353436
<p>Schema migrations, for example when you need to add a new column to an
33363437
existing table in your database, are not technically part of ORMs. However,
@@ -3342,10 +3443,7 @@ <h2>Schema migrations</h2>
33423443
<h3>General ORM resources</h3>
33433444
<ul>
33443445
<li>
3345-
<p>This article does a solid job of explaing what
3346-
<a href="http://www.agiledata.org/essays/impedanceMismatch.html">ORM impedance mismatch</a>
3347-
is at a high level and provides diagrams to visualize why the problem
3348-
occurs. There's also a detailed overview of <a href="http://www.agiledata.org/essays/mappingObjects.html">what ORMs are</a>
3446+
<p>There's also a detailed overview of <a href="http://www.agiledata.org/essays/mappingObjects.html">what ORMs are</a>
33493447
on another page of the website.</p>
33503448
</li>
33513449
<li>
@@ -3354,6 +3452,12 @@ <h3>General ORM resources</h3>
33543452
in an essay about how ORMs are often misused but that they do provide
33553453
benefits to developers.</p>
33563454
</li>
3455+
<li>
3456+
<p>If you're confused about the difference between a connector, such as
3457+
MySQL-python and an ORM like SQLAlchemy, read this
3458+
<a href="http://stackoverflow.com/questions/2550292/purpose-of-sqlalchemy-over-mysqldb">StackOverflow answer</a>
3459+
on the topic.</p>
3460+
</li>
33573461
</ul>
33583462
<h3>Django ORM resources</h3>
33593463
<ul>
@@ -3470,6 +3574,37 @@ <h3>Peewee resources</h3>
34703574
<a href="https://peewee.readthedocs.org/en/latest/">Peewee ORM</a> instead of
34713575
SQLAlchemy for the blog back end.</p>
34723576
</li>
3577+
</ul>
3578+
<h3>Pony ORM resources</h3>
3579+
<ul>
3580+
<li>
3581+
<p><a href="http://jakeaustwick.me/why-you-should-give-ponyorm-a-chance/">Why you should give Pony ORM a chance</a>
3582+
explains some of the benefits of Pony ORM that make it worth trying out.</p>
3583+
</li>
3584+
<li>
3585+
<p><a href="http://www.blog.pythonlibrary.org/2014/07/21/python-101-an-intro-to-pony-orm/">An intro to Pony ORM</a>
3586+
shows the basics of how to use the library, such as creating databases
3587+
and manipulating data.</p>
3588+
</li>
3589+
<li>
3590+
<p>The Pony ORM author explains on a Stack Overflow answer
3591+
<a href="http://stackoverflow.com/questions/16115713/how-pony-orm-does-its-tricks">how Pony ORM works behind the scenes</a>.
3592+
Worth a read whether or not you're using the ORM just to find out how
3593+
some of the magic coding works.</p>
3594+
</li>
3595+
</ul>
3596+
<h3>SQLObject resources</h3>
3597+
<ul>
3598+
<li>
3599+
<p>This post on
3600+
<a href="http://www.andypatterns.com/index.php/blog/object_relational_mapping_pattern_-_using_sqlobj/">Object-Relational Mapping with SQLObject</a>
3601+
explains the concept behind ORMs and shows the Python code for how they
3602+
can be used.</p>
3603+
</li>
3604+
<li>
3605+
<p>Ian Bicking presented on SQLObject back in 2004 with a talk on
3606+
<a href="http://www.ianbicking.org/docs/sqlobject-presentation/sqlobject-and-database-programming.html">SQLObject and Database Programming in Python</a>.</p>
3607+
</li>
34733608
</ul>
34743609
<h1>Application Programming Interfaces</h1>
34753610
<p>Application programming interfaces (APIs) provide machine-readable
@@ -6273,6 +6408,9 @@ <h1>Change Log</h1>
62736408
<h2>2015</h2>
62746409
<h3>June</h3>
62756410
<ul>
6411+
<li>Nice little update to the <a href="/object-relational-mappers-orms.html">ORMs page</a>
6412+
with a diagram showing that different ORMs can work with varying
6413+
web frameworks and backends.</li>
62766414
<li>Added a new section just for Nginx resources and Removed broken links on
62776415
the <a href="/web-servers.html">web servers</a> page.</li>
62786416
<li>Added a new page on Python

api-creation.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ <h3 class="panel-head"><a href="/table-of-contents.html" style="color: #fff;">Ta
314314
<a href="/data.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Data</a>
315315
<a href="/databases.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Databases</a>
316316
<a href="/no-sql-datastore.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>NoSQL Data Stores</a>
317-
<a href="/object-relational-mappers-orms.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Object-relational Mappers</a>
317+
<a href="/object-relational-mappers-orms.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Object-relational Mappers (ORMs)</a>
318318
<a href="/application-programming-interfaces.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Application Programming Interfaces</a>
319319
<a href="/api-integration.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>API Integration</a>
320320
<a href="/api-creation.html" class="list-group-item smaller-item active" style='font-family: "Helvetica Neue",sans-serif;'>API Creation</a>

api-integration.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ <h3 class="panel-head"><a href="/table-of-contents.html" style="color: #fff;">Ta
221221
<a href="/data.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Data</a>
222222
<a href="/databases.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Databases</a>
223223
<a href="/no-sql-datastore.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>NoSQL Data Stores</a>
224-
<a href="/object-relational-mappers-orms.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Object-relational Mappers</a>
224+
<a href="/object-relational-mappers-orms.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Object-relational Mappers (ORMs)</a>
225225
<a href="/application-programming-interfaces.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>Application Programming Interfaces</a>
226226
<a href="/api-integration.html" class="list-group-item smaller-item active" style='font-family: "Helvetica Neue",sans-serif;'>API Integration</a>
227227
<a href="/api-creation.html" class="list-group-item smaller-item " style='font-family: "Helvetica Neue",sans-serif;'>API Creation</a>

0 commit comments

Comments
 (0)