</p>
<&|doclib.myt:item, name="establishing", description="Establishing a Database Engine" &>
<p>
- Engines exist for SQLite, Postgres, MySQL, and Oracle, using the Pysqlite, Psycopg (1 or 2), MySQLDB, and cx_Oracle modules. Each engine imports its corresponding module which is required to be installed. For Postgres and Oracle, an alternate module may be specified at construction time as well.
+ Engines exist for SQLite, Postgres, MySQL, and Oracle, using the Pysqlite, Psycopg (1 or 2), MySQLDB, and cx_Oracle modules (there is also experimental support for Firebird). Each engine imports its corresponding module which is required to be installed. For Postgres and Oracle, an alternate module may be specified at construction time as well.
</p>
<p>The string based argument names for connecting are translated to the appropriate names when the connection is made; argument names include "host" or "hostname" for database host, "database", "db", or "dbname" for the database name (also is dsn for Oracle), "user" or "username" for the user, and "password", "pw", or "passwd" for the password. SQLite expects "filename" or "file" for the filename, or if None it defaults to "":memory:".</p>
<p>The connection arguments can be specified as a string + dictionary pair, or a single URL-encoded string, as follows:</p>
Tutorial\r
========\r
-In this tutorial we will guide you to get started with SQLAlchemy, Python SQL toolkit and Object Relational Mapper.\r
-SQLAlchemy provides a *lot* of functionality that will help you manage your SQL database. But very little is needed to know in order to begin doing useful things with it.\r
+This tutorial is a "quick start" guide to SQLAlchemy, the Python SQL Toolkit and Object Relational Mapper.\r
+SQLAlchemy provides a lot of functionality to help manage SQL databases, but you don't need much in order to begin doing useful things with it.\r
\r
-Note that it is not neccessary to read this tutorial, you may wish to skip it and dive into [main manual][manual].\r
+Note that it is not neccessary to read this tutorial; you may wish to skip it and dive into the [main manual][manual] which is more reference-oriented.\r
\r
[manual]: rel:howtoread\r
\r
[install setuptools]: http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions\r
[cheese]: http://cheeseshop.python.org/pypi\r
\r
-### Installing Database Manager {@name=dbms}\r
+### Installing A Database Manager {@name=dbms}\r
\r
-If you have one of the [supported database managers][supported dbms], you can proceed to the following section. Otherwise we recommend installing [SQLite][]. SQLite needs very little configuration and is easy to work with.\r
+ SQLAlchemy is designed to operate with the [DBAPI][DBAPI] built for a particular database, and includes implementations supporting the most popular ones. If you have one of the [supported database managers][supported dbms], you can proceed to the following section. Otherwise we recommend installing [SQLite][] for starters. SQLite needs very little configuration and is easy to work with.\r
+\r
+[DBAPI]: http://www.python.org/doc/peps/pep-0249/\r
\r
To work with SQLite, you'll need:\r
\r
* SQLite library\r
* [pysqlite][] - Python interface for SQLite\r
\r
-If you use Windows, you only have to download and install compiled [pysqlite binary][pysqlite]. It includes SQLite library, so you don't have to install it separately.\r
+If you use Windows, you only have to download and install the compiled [pysqlite binary][pysqlite]. It includes the SQLite library already linked in, so you don't have to install it separately.\r
\r
If you use Linux or FreeBSD, you may want to install pysqlite and SQLite from [packages][pysqlite packages] made for your operating system. Or you may install them [from sources][pysqlite].\r
\r
Get Going! {@name=getgoing}\r
--------------------------\r
\r
-### Connecting to Database\r
+### Connecting to the Database\r
\r
-First of all you need to connect to database you want to work with:\r
+First, you need to connect to the database you want to work with:\r
\r
>>> from sqlalchemy import *\r
- >>> db = create_engine('sqlite', {'filename': 'tutorial.db'})\r
+ >>> db = create_engine('sqlite://filename=tutorial.db')\r
\r
Main documentation: [dbengine](rel:dbengine).\r
\r
### Creating a Table {@name=table}\r
\r
-SQL tables and your domain classes are different beasts. That's why SQLAlchemy don't mix them. Let's construct an object that represents an SQL table:\r
+A core philosophy of SQLAlchemy is that tables and domain classes are different beasts. That's why SQLAlchemy doesn't mix them. So let's first work with just tables alone; we construct an object that represents a table:\r
\r
>>> users = Table('users', db,\r
... Column('user_id', Integer, primary_key = True),\r
... Column('password', String(80))\r
... )\r
\r
-As you can guess we have just defined a table `users` with 3 columns: `user_id` (which is a primary key), `user_name` and `password`. Currently it is just an object that may not correspond to existing table in your database. So let's create the real table! To make it interesting we will ask SQLAlchemy to echo SQL statements it sends to database:\r
+As you might have guessed, we have just defined a table `users` with 3 columns: `user_id` (which is a primary key column), `user_name` and `password`. Currently it is just an object that may not correspond to an existing table in your database. So let's create the real table! To make it interesting we will ask SQLAlchemy to echo the SQL statements it sends to the database:\r
\r
>>> db.echo = True\r
>>> users.create() # doctest:+ELLIPSIS,+NORMALIZE_WHITESPACE\r
...\r
>>> db.echo = False # you can skip this if you want to keep logging SQL statements\r
\r
-Alternatively, `users` table could already exist (e.g. you're running examples from this introduction for the second time). In this case you can just skip `create()` method call. You can even skip defining `users` table in your code and ask SQLAlchemy to load its definition from the database:\r
+Alternatively, the `users` table might already exist (such as, if you're running examples from this tutorial for the second time), in which case you can just skip the `create()` method call. You can even skip defining the individual columns in the `users` table and ask SQLAlchemy to load its definition from the database:\r
\r
>>> users = Table('users', db, autoload = True)\r
>>> list(users.columns)[0].name\r
\r
### Filling the Table\r
\r
-Ok, we have the table. To insert some data into the table you have to prepare a query first. You can use `insert()` method to do it:\r
+So now we have the table. To insert some data, use the `insert()` method to create a query:\r
\r
>>> i = users.insert()\r
>>> i # doctest:+ELLIPSIS\r
>>> print i\r
INSERT INTO users (user_id, user_name, password) VALUES (?, ?, ?)\r
\r
-Call `execute()` method of the prepared query to actually add users:\r
+Call the `execute()` method of the query object to actually add users:\r
\r
>>> for name in ['Tom', 'Dick', 'Harry']: # doctest:+ELLIPSIS\r
... i.execute(user_name = name)\r
>>> i.execute(user_name = 'Mary', password = 'secure') # doctest:+ELLIPSIS\r
<sqlalchemy.engine.ResultProxy instance at 0x...>\r
\r
-If possible, SQLAlchemy will bind values into a prepared query using native database API. This allows for better performance, because the database may cache compiled representation of the statement and reuse it between executions with different values. Also, when using bound values, you need not worry about [SQL injection][] attacks.\r
+SQLAlchemy will bind all literal values into bind parameters, according to the paramstyle of the underlying DBAPI. This allows for better performance, because the database may cache a compiled representation of the statement and reuse upon new executions, substituting the new values. Also, when using bound values, you need not worry about [SQL injection][] attacks.\r
\r
[SQL injection]: http://en.wikipedia.org/wiki/SQL_injection\r
\r
\r
### Querying the Table\r
\r
-Let's check that the data we have put into `users` table is actually there. The procedure is analogous to insert example above. The difference is that you have to call `select()` method now:\r
+Let's check that the data we have put into `users` table is actually there. The procedure is analogous to the insert example above, except you now call the `select()` function:\r
\r
>>> s = users.select()\r
>>> print s\r
FROM users\r
>>> r = s.execute()\r
\r
-Now we won't ignore return value of `execute()`:\r
+This time, we won't ignore the return value of `execute()`:\r
\r
>>> r # doctest:+ELLIPSIS\r
<sqlalchemy.engine.ResultProxy instance at 0x...>\r