<commit_before>Tutorial
========
This tutorial is a "quick start" guide to SQLAlchemy, the Python SQL Toolkit and Object Relational Mapper.
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.

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.

[manual]: rel:howtoread

Installation
------------

### Installing SQLAlchemy {@name=sqlalchemy}

Installing SQLAlchemy is easy if you have [setuptools][] on your system (if you don't, [install it][install setuptools], it's easy!). Just run this from the command-line:
    
    $ easy_install SQLAlchemy

This command will download the latest version of SQLAlchemy from the [Python Cheese Shop][cheese] and install it to your system.

[setuptools]: http://peak.telecommunity.com/DevCenter/setuptools
[install setuptools]: http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions
[cheese]: http://cheeseshop.python.org/pypi

### Installing A Database Manager {@name=dbms}

 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.

[DBAPI]: http://www.python.org/doc/peps/pep-0249/

To work with SQLite, you'll need:

  * SQLite library
  * [pysqlite][] - Python interface for SQLite

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.

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].

[supported dbms]: rel:dbengine_establishing
[sqlite]: http://sqlite.org/
[pysqlite]: http://pysqlite.org/
[pysqlite packages]: http://initd.org/tracker/pysqlite/wiki/PysqlitePackages

Get Going! {@name=getgoing}
--------------------------

### Connecting to the Database

First, you need to connect to the database you want to work with:

    >>> from sqlalchemy import *
    >>> db = create_engine('sqlite://filename=tutorial.db')

Main documentation: [dbengine](rel:dbengine).

### Creating a Table {@name=table}

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:

    >>> users = Table('users', db,
    ...     Column('user_id', Integer, primary_key = True),
    ...     Column('user_name', String(40)),
    ...     Column('password', String(80))
    ... )

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:

    >>> db.echo = True
    >>> users.create() # doctest:+ELLIPSIS,+NORMALIZE_WHITESPACE
    CREATE TABLE users(
        user_id INTEGER NOT NULL PRIMARY KEY,
        user_name VARCHAR(40),
        password VARCHAR(80)
    )
    ...
    >>> db.echo = False # you can skip this if you want to keep logging SQL statements

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:

    >>> users = Table('users', db, autoload = True)
    >>> list(users.columns)[0].name
    'user_id'

Main documentation: [metadata](rel:metadata).

### Filling the Table

So now we have the table. To insert some data, use the `insert()` method to create a query:

    >>> i = users.insert()
    >>> i # doctest:+ELLIPSIS
    <sqlalchemy.sql.Insert object at 0x...>
    >>> print i
    INSERT INTO users (user_id, user_name, password) VALUES (?, ?, ?)

Call the `execute()` method of the query object to actually add users:

    >>> for name in ['Tom', 'Dick', 'Harry']: # doctest:+ELLIPSIS
    ...     i.execute(user_name = name)
    <sqlalchemy.engine.ResultProxy instance at 0x...>
    ...
    >>> i.execute(user_name = 'Mary', password = '<PASSWORD>') # doctest:+ELLIPSIS
    <sqlalchemy.engine.ResultProxy instance at 0x...>

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.

[SQL injection]: http://en.wikipedia.org/wiki/SQL_injection

Main documentation: [sql_insert](rel:sql_insert).

### Querying the Table

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:

    >>> s = users.select()
    >>> print s
    SELECT users.user_id, users.user_name, users.password 
    FROM users
    >>> r = s.execute()

This time, we won't ignore the return value of `execute()`:

    >>> r # doctest:+ELLIPSIS
    <sqlalchemy.engine.ResultProxy instance at 0x...>
    >>> r.keys
    ['user_id', 'user_name', 'password']
    >>> row = r.fetchone()
    >>> row['user_name']
    u'Tom'
    >>> r.fetchall()
    [(2, u'Dick', None), (3, u'Harry', None), (4, u'Mary', u'secure')]

Main documentation: [sql_select](rel:sql_select).

### Related Table

Main documentation: [sql](rel:sql).

### Fancier Querying {@name=fancyquery}

Main documentation: [sql](rel:sql).

### Data Mapping {@name=mapping}

Main documentation: [datamapping](rel:datamapping), [adv_datamapping](rel:adv_datamapping).

### Transactions

Main documentation:  [unitofwork](rel:unitofwork), [dbengine_transactions](rel:dbengine_transactions).

Conclusion
----------<commit_msg>making the verbiage a little more formal...(its good stuff, just not sure what I want yet)<commit_after>Tutorial
========
This tutorial is a "quick start" guide to SQLAlchemy.  You may wish to skip it and dive into the [main manual][manual] which is more reference-oriented.

[manual]: rel:howtoread

Installation
------------

### Installing SQLAlchemy {@name=sqlalchemy}

Installing SQLAlchemy from scratch is most easily achieved with [setuptools][].  ([setuptools installation][install setuptools]). Just run this from the command-line:
    
    $ easy_install SQLAlchemy

This command will download the latest version of SQLAlchemy from the [Python Cheese Shop][cheese] and install it to your system.

[setuptools]: http://peak.telecommunity.com/DevCenter/setuptools
[install setuptools]: http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions
[cheese]: http://cheeseshop.python.org/pypi

### Installing A Database Manager {@name=dbms}

 SQLAlchemy is designed to operate with a [DBAPI][DBAPI] implementation built for a particular database, and includes support for the most popular databases. If you have one of the [supported database managers][supported dbms], you can proceed to the following section. Otherwise [SQLite][] is an easy to use database to get started with, requiring very little configuration.

[DBAPI]: http://www.python.org/doc/peps/pep-0249/

To work with SQLite, you'll need:

  * [pysqlite][] - Python interface for SQLite
  * SQLite library 

Note that the SQLite library download is not required with Windows, as the Windows Pysqlite library already includes it linked in.  Pysqlite and SQLite can also be installed on Linux or FreeBSD via pre-made [packages][pysqlite packages] or [from sources][pysqlite].

[supported dbms]: rel:dbengine_establishing
[sqlite]: http://sqlite.org/
[pysqlite]: http://pysqlite.org/
[pysqlite packages]: http://initd.org/tracker/pysqlite/wiki/PysqlitePackages

Getting Started {@name=gettingstarted}
--------------------------

### Connecting to the Database

First, you need to connect to the database you want to work with:

    >>> from sqlalchemy import *
    >>> db = create_engine('sqlite://filename=tutorial.db')

Documentation on creating engines is available in [dbengine](rel:dbengine).

### Creating a Table {@name=table}

A core philosophy of SQLAlchemy is that tables and domain classes are different beasts.  For this reason, SQLAlchemy provides constructs that represent tables by themselves (known as *table metadata*).  So we will begin by constructing table metadata objects and performing SQL operations with them directly, keeping in mind that there is also an Object Relational Mapper (ORM) which does the same thing except via domain models.  Let's construct an object that represents a table:

    >>> users = Table('users', db,
    ...     Column('user_id', Integer, primary_key = True),
    ...     Column('user_name', String(40)),
    ...     Column('password', String(80))
    ... )

As you might have guessed, we have just defined a table named `users` which has three 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.  To actually create the table, we use the `create()` method.  To make it interesting we will have SQLAlchemy to echo the SQL statements it sends to the database:

    >>> db.echo = True
    >>> users.create() # doctest:+ELLIPSIS,+NORMALIZE_WHITESPACE
    CREATE TABLE users(
        user_id INTEGER NOT NULL PRIMARY KEY,
        user_name VARCHAR(40),
        password VARCHAR(80)
    )
    ...
    >>> db.echo = False # you can skip this if you want to keep logging SQL statements

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:

    >>> users = Table('users', db, autoload = True)
    >>> list(users.columns)[0].name
    'user_id'

Documentation on table metadata is available in [metadata](rel:metadata).

### Inserting Rows

Inserting is achieved via the `insert()` method, which defines a *clause object* representing an INSERT statement:

    >>> i = users.insert()
    >>> i # doctest:+ELLIPSIS
    <sqlalchemy.sql.Insert object at 0x...>
    >>> print i
    INSERT INTO users (user_id, user_name, password) VALUES (?, ?, ?)

The `execute()` method of the clause object executes the statement at the database level:

    >>> for name in ['Tom', 'Dick', 'Harry']: # doctest:+ELLIPSIS
    ...     i.execute(user_name = name)
    <sqlalchemy.engine.ResultProxy instance at 0x...>
    ...
    >>> i.execute(user_name = 'Mary', password = 'secure') # doctest:+ELLIPSIS
    <sqlalchemy.engine.ResultProxy instance at 0x...>

When constructing clause objects, SQLAlchemy will bind all literal values into bind parameters, according to the paramstyle of the underlying DBAPI. This allows for better performance, as the database may cache a compiled representation of the statement and reuse it for new executions, substituting the new values. Also, when using bound values, you need not worry about [SQL injection][] attacks.

[SQL injection]: http://en.wikipedia.org/wiki/SQL_injection

Documentation on inserting: [sql_insert](rel:sql_insert).

### Constructing Queries

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()` method off the `users` table:

    >>> s = users.select()
    >>> print s
    SELECT users.user_id, users.user_name, users.password 
    FROM users
    >>> r = s.execute()

This time, we won't ignore the return value of `execute()`:

    >>> r # doctest:+ELLIPSIS
    <sqlalchemy.engine.ResultProxy instance at 0x...>
    >>> r.keys
    ['user_id', 'user_name', 'password']
    >>> row = r.fetchone()
    >>> row['user_name']
    u'Tom'
    >>> r.fetchall()
    [(2, u'Dick', None), (3, u'Harry', None), (4, u'Mary', u'secure')]

Documentation on selecting: [sql_select](rel:sql_select).

### Related Table

Main documentation: [sql](rel:sql).

### Fancier Querying {@name=fancyquery}

Main documentation: [sql](rel:sql).

### Data Mapping {@name=mapping}

Main documentation: [datamapping](rel:datamapping), [adv_datamapping](rel:adv_datamapping).

### Transactions

Main documentation:  [unitofwork](rel:unitofwork), [dbengine_transactions](rel:dbengine_transactions).

Conclusion
----------
{'fraction_non_alphanumeric': 0.11321328166552694, 'fraction_numerical': 0.003115264797507788, 'mean_word_length': 4.085780525502319, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 138, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1981851', 'n_tokens_mistral': 3868, 'n_tokens_neox': 3654, 'n_words': 1513}