del.icio.us,Dig IT

Download this page in : in pdf, in OpenOffice odt file

Contents

  1. Start Here
    1. Short Intro To TurboGears
    2. Search TG docs
  2. Install TurboGears
  3. QuickStart a new project
    1. Create project
    2. Start the project
    3. Make changes
  4. Turbogears Overview
    1. Add,remove URL in controller.py
    2. Database settings
    3. Database tables using model.py
    4. Kid template
  5. First webapp: Address Book
    1. Database Model
      1. Import Proper Modules
      2. Create Tables
      3. Map Your Table To Python Class
      4. Create Tables in Database
    2. TurboGears Flow
      1. Template
      2. Save Form
      3. Edit form
  6. TurboGears in Second(II) Gear
    1. TurboGears Forms
      1. Widgets and Validators
      2. Form Widget
      3. Page URL
      4. Page template
      5. Validate the widget/form
      6. More on Validate Widget
      7. Pre-fill Widgets
      8. Widgets options
      9. Validators options
      10. Password validators
      11. Focus cursor on the form field
    2. TurboGears dispaly Widgets
      1. DataGrid
      2. DataGrid and SqlAlchemy Example
      3. Data Grid Example with static content
      4. Paginate Data Grid
      5. Fast Data Grid
  7. SqlAlchemy (SA)
    1. Database Connection
      1. What needs to be imported
      2. bind to database
      3. create tables
      4. create python data class
      5. map database to python class
    2. create table in sqlalchemy
      1. datatypes
      2. autoload
      3. Primary, auto increment, unique, alternative, composite keys
    3. controller.py, Data passing and conversion
    4. Direct Sql statements to a database
    5. Basic select()
      1. equal, not equal, less then, more then
      2. more or less
      3. and ,or ,not
      4. like, endswith, startswith, between, in
    6. Advenced select()
      1. different select: sqlalchemy.select()
      2. group_by
      3. select_by
    7. available functions of sqlalchemy
      1. properties of python class and sql
      2. properties of a field name
      3. list of available fields, proprties
      4. working with columns
      5. Select() function properties
      6. get() function
    8. insert record
    9. update record
      1. Dispaly record
    10. Flow Control: update,submit,save,display
    11. Saving table with many columns
    12. Saving multiple records
    13. sqlalchemy in virtualenv
  8. Session Managment
    1. Session ID
  9. Install Turbogears with Apache
    1. apache and mod_wsgi
      1. Install mod_wsgi
      2. Configure your Turbogears app for mod_wsgi
      3. Turbogears and modwsgi in VirtualHost,virtualenv, and subdomain
      4. Enable your website
      5. advence mod_wsgi memory management
      6. Stress test your app
    2. Egg deploy
      1. Create an Egg File
      2. dev.cfg app.cfg prod.cfg
      3. Deploy an EGG file
      4. Configure TurboGears prod.cfg
      5. Run the app
    3. Mod_Proxy
      1. Enable mod proxy
      2. Configure apache
      3. Auto start of the app
      4. Server Log
    4. mod_python
      1. Install project file
      2. Test project file
      3. Configure apache2 with your turbogears project
      4. Error
  10. Turbogears API Details
    1. Packages
    2. Modules
    3. Classes
  11. Performance
    1. Genshi vs other
    2. maco vs Cheetah
    3. Sqlalchemy vs storm
  12. Errors
    1. TgFastData for python 2.5
  13. EXTRA
    1. Produce PDF Pages
    2. MyTube with Flex and Turbogears
    3. captcha widgets for a form
    4. Basic Way to display column data from a database
    5. Identity Management
    6. TurboGears with existing MySQL database
    7. Flash status Bar
    8. Tagging with Turbogears
    9. Drag and Drop Sort list
    10. Turbogears and Oracle
    11. Turbogears memory managment
    12. unixODBC
    13. Authenticating against an external password source
    14. Embed swf files in your turbogears code (IE, Opera, Firefox etc)
    15. SQLObject (SO) quick Overview
      1. dev.conf -database connection
      2. model.py -database model
      3. sqlobject features
      4. SQLObject save to database
  14. Turbogears Specifics usage
    1. Use CAPITAL names in widgets and sqlalchemy autoload
    2. redirect all requests to index
  15. Other Documentation
    1. IBM
    2. ORACLE
  16. Common Errors
    1. non-keyword arg after keyword arg
    2. cherrypy._cperror.NotReady: Port not free
    3. ExpatError: not well-formed (invalid token)
    4. Could not assemble any primary key columns for mapped table
Original Document is located here: http://lucasmanual.com/mywiki/TurboGears

Turbogears2 documentation is located here: http://lucasmanual.com/mywiki/TurboGears2

Keywords: Tutorial, TurboGears, SqlObject, SqlAlchemy, web, python, features, Linux, windows, database, mysql, Examples, web, cherrypy, manual, easy, first time to turbogears, documentation, solutions, fixed, solved,working, pylones, python web framework, TurboGears widgets, TurboGears Forms, TurboGears controller, TurboGears model, TurboGears and sqlalchemy, TurboGears and AJAX, Turbogears Documentation, Turbogears Manual, Turbogears Howto, Turbogears how to, Turbogears faq,trubogears

Start Here

Welcome.

  1. Please start from the beginning of this page if you are new to TurboGears.

  2. If you are looking for something specific please go over the menu items.

  3. If you want to view TurboGears API documentation see: TurboGears API Documentation

Short Intro To TurboGears

If it is your first time working with turbogears, this TurboGears Article will give you an overview of what is what in turbogears. It will show you how turbogears connects database, templates, javascript via python in one simple framework. Here is a copy of just Turbogears related pages Turbogears in O3 Magazine, Issue5 (copy)

Search TG docs

Just looking for specific information? Look through menu first, then try TurboGears Search engine

Install TurboGears

For Turbogears to work we need the following items.

  1. Turbogears.
  2. Sqlite, python bindings for sqlite or mysql and mysql python bindings.

We will use Linux since it is the easiest operating system to work with.

aptitude update
aptitude install python-turbogears

aptitude install sqlite3
aptitude install python-pysqlite2

aptitude install mysql-server
aptitude install python-mysqldb

You are ready to start your turbogears development.

QuickStart a new project

Create project

tg-admin quickstart --sqlalchemy

Enter project name: myfirstproject
Enter package name [myfirstproject]

Start the project

python start-myfirstproject.py

Make changes

Just go into your project folder, inside there should be:

  1. dev.cfg - where you set configuration properties for your project.
  2. setup.py - which you can use to install your python project into python site-package
  3. myfirstproject folder - There is a folder with a same name as your project, inside there are:
    1. templates - which hold all your html templates (welcome.kid)
    2. static - which holds your images, css, and javascript
    3. config- where you will find your app specific configuration.
    4. model.py - which has your data models
    5. controller.py - which has your data manipulations, your urls, etc.

You can start by editing the main page. In my case I go to myfirstproject/templates and in there you can find the welcome.kid . It is an xhtml file so you can change some text and see how they show up immediately in http:localhost:8080.

Turbogears Overview

Add,remove URL in controller.py

    @expose(template="myfirstproject.templates.welcome")
    def index(self):
        import time
        # log.debug("Happy TurboGears Controller Responding For Duty")
        return dict(now=time.ctime())

    @expose(template="myfirstproject.templates.hello")
    def hello(self):
        import time
        # log.debug("Happy TurboGears Controller Responding For Duty")
        return dict(greeting="Hello from a controller.py")

Database settings

sqlalchemy.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"

If you want to use a true database from a start you can use syntax like this for:

sqlalchemy.dburi="mysql://username:password@hostname:3306/databasename"
sqlalchemy.dburi="postgres://username:password@hostname/databasename
sqlalchemy.dburi="oracle://username:password@hostname:1521/sidname"
sqlalchemy.dburi="mssql://username:password@hostname:1433/databasename?driver=TDS"

You don't have to provide the port as sqlalchemy knows default ports.

Database tables using model.py

from sqlalchemy import *
to
import sqlalchemy

address_table = sqlalchemy.Table('address', metadata,
    sqlalchemy.Column('Address_Sid', sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column('FirstName', sqlalchemy.Unicode(40),nullable=False),
    sqlalchemy.Column('LastName', sqlalchemy.Unicode(40),nullable=False),
    sqlalchemy.Column('MaidenLastName', sqlalchemy.Unicode(40)),
    sqlalchemy.Column('Email', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('Address', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('City', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('State', sqlalchemy.String(2),nullable=False),
    sqlalchemy.Column('ZipCode', sqlalchemy.Integer,nullable=False),
    sqlalchemy.Column('DOB', sqlalchemy.Date(),nullable=False),
    sqlalchemy.Column('CreatedDate', sqlalchemy.Date, default=datetime.now().date()),
    sqlalchemy.Column('CreatedTime', sqlalchemy.Time, default=datetime.now().time())
    )

tg-admin sql create

Kid template

py:content    -Replace content inside of a tag <a py:content> replace this text</a>
py:if         -Do if statement: py:if="x" if x is true display, else it will remove the tag and its children.
py:for        -Do for loop
py:replace    -Replace whole tag: <a py:replace="<a> my default meta tag</meta>"\>
py:strip
py:match      -Matches a tag in a template and replaces with the content you specify.(headers,footers)
py:def

<?python
myvariable = 'i want this text to replace the variable name in template'
?>
<span py:content="myvariable">Text to be replaced</span>

<div py:content="document('header.html')">Replace this text</div>

<meta content="text/html";charset=UTF-8" http-equiv="content-type" py:replace="''"/>

<ul>
    <li py:for="person in PhoneBook">
        <a href="$person.home_page">
            <span py:content="person.last_name">Name to be replaced</span>,
            <span py:content="person.first_name">Name to be replaced</span>
        </a>

 <div py:if="person.first_name and person.last_name" >
            <span py:content="person.last_name">Name to be replaced</span>,
            <span py:content="person.first_name">Name to be replaced</span>
</div>

or

 <div py:if="value_of('somefield', None)" py:content="somecontent"></div>

or

<p py:if="5 * 5 == 25">
  Python seems to be handling multiplication okay.
</p>

First webapp: Address Book

tg-admin quickstart --sqlalchemy

sqlalchemy.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
sqlalchemy.dburi="mysql://username:password@hostname:3306/databasename"
sqlalchemy.dburi="postgres://username:password@hostname/databasename
sqlalchemy.dburi="oracle://username:password@hostname:1521/sidname"
sqlalchemy.dburi="mssql://username:password@hostname:1433/databasename?driver=TDS"

You don't have to provide the port as sqlalchemy knows default ports.

Database Model

Before we start lets make sure you have all modules imported and you know what is for what.

  1. Make sure you imported proper modules.
  2. Define your tables. 1.Create and bind your database to python class.

Import Proper Modules

  1. You should see an import statements like this(if you don't need identity this list will be shorter):

from datetime import datetime   #this imports date and time manipulation library
from turbogears.database import metadata, mapper   #This maps database to a python class (more on it soon)

# import some basic SQLAlchemy classes for declaring the data model
# (see http://www.sqlalchemy.org/docs/04/ormtutorial.html)
from sqlalchemy import Table, Column, ForeignKey
from sqlalchemy.orm import relation

# import some datatypes for table columns from SQLAlchemy
# (see http://www.sqlalchemy.org/docs/04/types.html for more)
#from sqlalchemy import String, Unicode, Integer, DateTime,Time,Date, TEXT
import sqlalchemy
from turbogears import identity

Create Tables

Define a table

#Your table definition here.
address_table = sqlalchemy.Table('addressbook', metadata,
    sqlalchemy.Column('Address_Sid', sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column('FirstName', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('LastName', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('MaidenLastName', sqlalchemy.Unicode(40)),
    sqlalchemy.Column('Email', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('Address', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('City', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('State', sqlalchemy.String(2),nullable=False),
    sqlalchemy.Column('ZipCode', sqlalchemy.Integer,nullable=False),
    sqlalchemy.Column('DOB', sqlalchemy.Date(),nullable=False),
    sqlalchemy.Column('CreatedDate', sqlalchemy.Date, default=datetime.now().date()),
    sqlalchemy.Column('CreatedTime', sqlalchemy.Time, default=datetime.now().time())
    )

Map Your Table To Python Class

Create a python class

#Object Creation
#This is an empty class that will become our data class
class Addressbook(object):
    pass

Map python class

#Mapping of Table to Object
addresstable_mapper=mapper(Addressbook,address_table)

Note: Sqlalchemy 0.3, assign_mapper has been depreciated and default is to use a mapper. If you are looking for assign_mapper functionality take a look at Elixir Project.

Create Tables in Database

tg-admin sql create

If you experience problems or errors go back to installation and make sure you have all the components. If that doesn't fix the error check your model.py

TurboGears Flow

    @expose(template="myfirstproject.templates.addresses")
    def addresses(self):
        from model import Addressbook
        x=Addressbook.select()
        return dict(addresses=x)

Template

<body>
<ul>
    <li py:for="record in addresses">
        <a py:content="record.FirstName">first name</a>
        <a py:content="record.LastName">last name</a>
    </li>
</ul>
</body>

Visit: http://localhost:8080/addresses

We now finished with displaying addresses. Now its time to create a form so we can insert them.

Save Form

from turbogears import controllers, expose

add redirect at the end of list.

from turbogears import controllers, expose, redirect

    @expose()
    def saveaddressbook(self,first_name,last_name):
        from model import AddressBook
        first_name=first_name
        last_name=last_name
        AddressBook(first_name=first_name,last_name=last_name)
        raise redirect("/addresses")

This function expects the first and last name to be passed into it.You can reach this function at localhost:8080/saveaddressbook but it will give you an error if you don't pass first and last name. It will save names using the Addressbook Class from the model. At the end it will redirect to localhost:8080/addresses

Edit form

    @expose(template="myfirstproject.templates.form")
    def addressbookform(self):
        return dict()

<body>
<form NAME="Add Addressbook" METHOD="post" ACTION="/saveaddressbook">
<p>First Name: <input name="first_name"></input></p>
<p>Last Name: <input name="last_name"></input></p>
<p><input type="submit" value="submit"></input></p>
</form>
</body>

ExpatError: mismatched tag: line 13, column 2

TurboGears in Second(II) Gear

TurboGears Forms

Widgets and Validators

Form Widget

from turbogears import controllers, expose, widgets, validators, error_handler, validate

class AddressBookFields(widgets.WidgetsList):
    firstname = widgets.TextField(validator=validators.NotEmpty)
    description = widgets.TextArea(validator=validators.NotEmpty)
    homepage = widgets.TextField(validator=validators.URL)
    yourcarvalue = widgets.TextField(label="Car Value", validator=validators.Money(not_empty=True))
    zipcode = widgets.TextField(label="ZipCode",validator=validators.PostalCode)

addressbook_form = widgets.TableForm(fields=AddressBookFields(),submit_text="save address")

Below you will find an example of choices you can make when creating widget:

class BigAddressBookFields(widgets.WidgetsList):
    firstname = widgets.TextField(validator=validators.NotEmpty)
    description = widgets.TextArea(validator=validators.NotEmpty)
    homepage = widgets.TextField(validator=validators.URL)
    yourcarvalue = widgets.TextField(label="Car Value", validator=validators.Money(not_empty=True))
    zipcode = widgets.TextField(label="ZipCode",validator=validators.PostalCode)
    age = widgets.TextField(label="Your Age",validator=validators.Int)
    sex = widgets.SingleSelectField(label="Gender",validator=validators.NotEmpty, options=['Female','Male'])
    maritalstatus = widgets.SingleSelectField(label="Marital Status", validator=validators.NotEmpty,options=['Single','Married'])
    dob = widgets.CalendarDatePicker(format = '%Y/%m/%d',validator = validators.DateTimeConverter(format="%Y/%m/%d"))
    year=widgets.TextField(attrs={'size':4,'maxlength':4},validator=validators.All(validators.Number(not_empty='True'),validators.MinLength(4)))
    searchin = widgets.RadioButtonList(label="Search in",validator=validators.NotEmpty,options=['Option1','Option2'])
    searchfor = widgets.RadioButtonList(label="Search For",validator=validators.NotEmpty,options=['Option1','Option2'],default='Option1')
    searchtype = widgets.RadioButtonList(label="Search Type",validator=validators.NotEmpty, options=[(1,'Exact'),(2,'Slow')],default=1)

myfield = widgets.TextField(
name='title', label='Title',
attrs={'size': 64, 'maxlength': 64},
validator=v.All(validators.NotEmpty, validators.UnicodeString)
)

Page URL

    @expose(template="addressbook.templates.form")
    def addressbook(self):
        submit_action = "/addressbookprocess"
        return dict(form=addressbook_form,action=submit_action)
  1. First line tells you which template will be used.
  2. Second line tells you what will be the url of this method. http://localhost:8080/addressbook

  3. Submit action tells where should the form input be sent.
  4. Last line returns a dictionary 'form', which is equal to addressbook_form, and we pass an action as well.

Page template

<body>
${form(action=action)}
</body>

Validate the widget/form

    @expose()
    @error_handler(addressbook)
    @validate(form=addressbook_form)
    def addressbookprocess(self,**kwargs):
        return dict(kwargs=kwargs)

If you are building a registration forms you might want to try:Registration for TG. It is a set of tools to help you register users.

More on Validate Widget

from turbogears import redirect, widgets,validators, error_handler, validate,flash

class AddressBookFields(widgets.WidgetsList):
    firstname = widgets.TextField(validator=validators.NotEmpty)
    description = widgets.TextArea(validator=validators.NotEmpty)
    homepage = widgets.TextField(validator=validators.URL)

# Create object and set submit button text
address_form = widgets.TableForm(fields=AddressBookFields(),submit_text="save address")

 @expose(template="addressbook.templates.addressupdate")
    def addressupdate(self):
        submit_action = "/addresssave"
        return dict(form=address_form,action=submit_action)

<html>
<body>
<p> ${form(action=action)} </p>
</body>
</html>

    #@expose(template="addressbook.templates.addresssave")
    @expose()
    @error_handler(addressupdate)
    @validate(form=address_form)
    def addresssave(self,**kwargs):
        flash('Addressbook Information are Saved')
        #You can save the information stored in dictionary kwargs to your database, proccess data, etc
        # return dict(kwargs=kwargs) or raise redirect("/index") or return other information.
        return dict(kwargs=kwargs)

Pre-fill Widgets

d=model.Useraddress()
x=d.get_by(USER_SID=345,ADDRESS_SID=2)

Then I pass x(the corresponding record) to my template

return dict(address=address_form,value=x, action=submit_action)

 <p><span>${address(value=value, action=action)}</span></p>

Widgets options

import turbogears

dir(turbogears.widgets)

['AjaxGrid', 'AutoCompleteField', 'Button', 'CSSLink', 'CSSSource', 'CalendarDat
ePicker', 'CalendarDateTimePicker', 'CalendarLangFileLink', 'CheckBox', 'CheckBo
xList', 'CompoundFormField', 'CompoundInputWidget', 'CompoundWidget', 'DataGrid'
, 'FieldSet', 'FileField', 'Form', 'FormField', 'FormFieldsContainer', 'HiddenFi
eld', 'ImageButton', 'InputWidget', 'JSLink', 'JSSource', 'JumpMenu', 'Label', '
Link', 'LinkRemoteFunction', 'ListForm', 'LocalizableJSLink', 'MultipleSelectFie
ld', 'PaginateDataGrid', 'PasswordField', 'RPC', 'RadioButtonList', 'RemoteForm'
, 'RepeatingFieldSet', 'RepeatingFormField', 'RepeatingInputWidget', 'ResetButto
n', 'Resource', 'SelectionField', 'SingleSelectField', 'Source', 'SubmitButton',
 'SyntaxHighlighter', 'Tabber', 'TableForm', 'TextArea', 'TextField', 'URLLink',
 'Widget', 'WidgetDescription', 'WidgetsList', '__builtins__', '__doc__', '__fil
e__', '__name__', '__path__', 'all_widgets', 'base', 'big_widgets', 'datagrid',
'forms', 'i18n', 'js_location', 'links', 'load_widgets', 'meta', 'mochikit', 're
gister_static_directory', 'rpc', 'set_with_self', 'static']

Validators options

import turbogears
dir(turbogears.validators)

['All', 'Any', 'Bool', 'ConfirmType', 'Constant', 'CreditCardExpires', 'CreditCa
rdSecurityCode', 'CreditCardValidator', 'DateConverter', 'DateTimeConverter', 'D
ateValidator', 'DictConverter', 'Email', 'Empty', 'FancyValidator', 'FieldStorag
eUploadConverter', 'FieldsMatch', 'FileUploadKeeper', 'ForEach', 'FormValidator'
, 'IndexListConverter', 'Int', 'Invalid', 'JSONValidator', 'MaxLength', 'MinLeng
th', 'Money', 'MultipleSelection', 'NoDefault', 'NotEmpty', 'Number', 'OneOf', '
PhoneNumber', 'PlainText', 'PostalCode', 'Regex', 'RequireIfMissing', 'RequireIf
Present', 'Schema', 'Set', 'SignedString', 'StateProvince', 'String', 'StringBoo
l', 'StringBoolean', 'StripField', 'TgFancyValidator', 'TimeConverter', 'URL', '
UnicodeString', 'Validator', 'Wrapper', '_', '__builtin__', '__builtins__', '__d
oc__', '__file__', '__name__', '_findall', '_illegal_s', 'cgi', 'datetime', 'for
mat', 'jsonify', 'pkg_resources', 're', 'simplejson', 'strftime_before1900', 'ti
me', 'turbogears', 'util', 'validators', 'warnings']

Password validators

class PasswordFields(widgets.WidgetsDecalration):
    passwd = widgets.PasswordField(validators=validators.NotEmpty())
    passwd2 = widgets.PasswordField(validators=validators.UnicodeString())
class PasswordSchema(fromencode.schema.Schema):
    chained_validators=[validators.FieldsMatch('passswd','passwd2')]

form = TableForm(fields=PasswordFields(), validator=PasswordSchema)

Focus cursor on the form field

<body onload="document.getElementById('myfield').focus()">

TurboGears dispaly Widgets

DataGrid

DataGrid and SqlAlchemy Example

from turbogears.widgets import DataGrid

myusers_datagrid = DataGrid(fields=[
    ('DisplayedColumnName1', 'LastName'),
    ('DisplayedColumnName2', 'FirstName'),
    ('DisplayedColumnName3', 'PhoneNumber'),
    ])

mydatagrid=myusers_datagrid.display(Users.select())
retrun dict(mydatagrid=mydatagrid)

<span py:content="mydatagrid">datagrid will appear here</span>

Data Grid Example with static content

from turbogears.widgets import DataGrid

mycustom_widget = DataGrid(fields=[
    ('NumberOfPayments', lambda row=row[0]),
    ('Due Each Month', lambda row=row[1]),
])

mydefaults=[(6,100),(2,300)]

        from model import *
        mydatagrid=mycustome_widget.display(mydefaults)
        return dict(mydatagrid=mydatagrid)

<span py:content="mydatagrid">datagrid will appear here</span>

Paginate Data Grid

You need to import paginate, so your import lines need to have paginate, and url from turbogears, and PaginateDataGrid from widget.

from turbogears import controllers, expose, flash,widgets, validators, error_handler, validate, paginate, url
from turbogears.widgets import PaginateDataGrid

#Create Sortable Option
sortable = dict(sortable=True)

mytable_grid = PaginateDataGrid(name='my big results',
    fields=[
        ('ID', 'id', sortable),
        ('Groupname', 'group_name'),
        ('Last Name', 'last_name', sortable),
        ('Members', 'num_members', sortable)
])

    @expose(template="myapp.templates.mybigpage")
    @paginate('myresults',limit=50,default_order='last_name')
    def mybigpage(self):
        #do some query here myresults=.....
        return dict(mytablegrid=mytable_grid,myresults=myresults)

*In your template add:

<p><span py:content="mytablegrid(myresults)">My Grid will show here.</span></p>

Fast Data Grid

sudo easy_install -f http://turbogears.org/download/ TGFastData

SqlAlchemy (SA)

tg-admin quickstart --sqlalchemy

Database Connection

Setup the connection

sqlalchemy.dburi="mysql://username:password@localhost:3306/databasename

sqlalchemy.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
sqlalchemy.dburi="mysql://username:password@hostname:3306/databasename"
sqlalchemy.dburi="postgres://username:password@hostname/databasename
sqlalchemy.dburi="oracle://username:password@hostname:1521/sidname"

sqlalchemy.dburi="mssql://username:password@hostname:1433/databasename?driver=TDS&odbc_options='TDS_Version=8.0'"

You don't have to provide the port as sqlalchemy knows default ports.

What needs to be imported

from turbogears.database import metadata, session, bind_meta_data
from sqlalchemy.ext.assignmapper import assign_mapper
import sqlalchemy

bind to database

bind_meta_data()

create tables

Load Existing Table

#Creating table sctructure from our database.
yourtablename_table = sqlalchemy.Table('yourtablename', metadata, autoload=True)

Create your own table

address_table = sqlalchemy.Table('address', metadata,
    sqlalchemy.Column('Address_Sid', sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column('FirstName', sqlalchemy.Unicode(40),nullable=False),
    sqlalchemy.Column('LastName', sqlalchemy.Unicode(40),nullable=False),
    sqlalchemy.Column('MaidenLastName', sqlalchemy.Unicode(40)),
    sqlalchemy.Column('Email', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('Address', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('City', sqlalchemy.Unicode(80),nullable=False),
    sqlalchemy.Column('State', sqlalchemy.String(2),nullable=False),
    sqlalchemy.Column('ZipCode', sqlalchemy.Integer,nullable=False),
    sqlalchemy.Column('DOB', sqlalchemy.Date(),nullable=False),
    sqlalchemy.Column('CreatedDate', sqlalchemy.Date, default=datetime.now().date()),
    sqlalchemy.Column('CreatedTime', sqlalchemy.Time, default=datetime.now().time())
    )

tg-admin sql create

Captialized refers to a SQL standard type, whereas non-capitalized is a "generic" type that may resolve differently on different database backends.

module sqlalchemy.types

    * class BLOB(Binary)
    * class BOOLEAN(Boolean)
    * class Binary(TypeEngine)
    * class Boolean(TypeEngine)
    * class CHAR(String)
    * class CLOB(TEXT)
    * class DATE(Date)
    * class DATETIME(DateTime)
    * class DECIMAL(Numeric)
    * class Date(TypeEngine)
    * class DateTime(TypeEngine)
    * class FLOAT(Float)
    * class Float(Numeric)
    * class INT(Integer)
    * class Integer(TypeEngine)
    * class Interval(TypeDecorator)
    * class NCHAR(Unicode)
    * class NUMERIC(Numeric)
    * class Numeric(TypeEngine)
    * class PickleType(MutableType,TypeDecorator)
    * class SMALLINT(SmallInteger)
    * class SmallInteger(Integer)
    * class String(Concatenable,TypeEngine)
    * class TEXT(String)
    * class TIME(Time)
    * class TIMESTAMP(DateTime)
    * class Time(TypeEngine)
    * class TypeDecorator(AbstractType)
    * class TypeEngine(AbstractType)
    * class Unicode(String)
    * class VARCHAR(String)

create python data class

#Object Creation
#This is an empty class that will become our data class
class Yourtablename(object):
    pass

map database to python class

#Mapping of Table to Object
yourtablename_mapper=assign_mapper(session.context,Yourtablename,yourtablename_table)

from turbogears.database import metadata, session,bind_meta_data
from sqlalchemy.ext.assignmapper import assign_mapper
import sqlalchemy


#Binding sqlalchemy to a turbogears database
bind_meta_data()

#[Mysql option]Fixed in next relese. Table creation, ticket 482
#from turbogears import database
#engine=database.get_engine()
#tables = []
#for name in engine.execute("SHOW TABLES"):
#   tables[name] = sqlalchemy.Table(name, metadata, autoload=True)

#Using manual table creation
binder_table = sqlalchemy.Table('binder', metadata, autoload=True)
bdriver_table = sqlalchemy.Table('bdriver', metadata, autoload=True)
bcoverage_table = sqlalchemy.Table('bcoverage', metadata, autoload=True)
bvehicle_table = sqlalchemy.Table('bvehicle', metadata, autoload=True)
bviolation_table = sqlalchemy.Table('bviolation', metadata, autoload=True)
bdiscschg_table = sqlalchemy.Table('bdiscschg', metadata, autoload=True)

#Object Creation
#This is an empty class that will become our data class
class Binder(object):
    pass
class bdriver(object):
    pass
class bcoverage(object):
    pass
class bvehicle(object):
    pass
class bviolation(object):
    pass
class bdiscschg(object):
    pass

#Mapping of Table to Object
bindermapper=assign_mapper(session.context,Binder,binder_table)
bdrivermapper=assign_mapper(session.context,bdriver,bdriver_table)
bvehiclemapper=assign_mapper(session.context,bvehicle,bvehicle_table)
bcoveragemapper=assign_mapper(session.context,bcoverage,bcoverage_table)
bviolationmapper=assign_mapper(session.context,bviolation,bviolation_table)
bdiscschmapper=assign_mapper(session.context,bdiscschg,bdiscschg_table)

When Done Don't forget to run this command in root directory of the project.

tg-admin sql create

create table in sqlalchemy

datatypes

address_table = sqlalchemy.Table('address', metadata,
    sqlalchemy.Column('Address_Sid', sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column('FirstName', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('LastName', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('MaidenLastName', sqlalchemy.Unicode(128)),
    sqlalchemy.Column('Email', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('Address', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('City', sqlalchemy.Unicode(128),nullable=False),
    sqlalchemy.Column('State', sqlalchemy.String(2),nullable=False),
    sqlalchemy.Column('ZipCode', sqlalchemy.Integer,nullable=False),
    sqlalchemy.Column('DOB', sqlalchemy.Date(),nullable=False),
    sqlalchemy.Column('CreatedDate', sqlalchemy.Date, default=datetime.now().date()),
    sqlalchemy.Column('CreatedTime', sqlalchemy.Time, default=datetime.now().time())
    )

autoload

Primary, auto increment, unique, alternative, composite keys

unique

# per-column anonymous unique constraint
Column('col1', Integer, unique=True),

Column('col2', Integer),
Column('col3', Integer),

# explicit/composite unique constraint.  'name' is optional.
UniqueConstraint('col2', 'col3', name='uix_1')

controller.py, Data passing and conversion

In controller you you to add this to import lines if they don't have it included:

from quote import model

Direct Sql statements to a database

from turbogears import database
engine=database.get_engine()
engine.execute("SHOW TABLES"):

Basic select()

s=Users.select()

equal, not equal, less then, more then

s1=Users.select(Users.c.LASTNAME=='Smith')

more or less

s1=Users.select(Users.c.AGE < 40)

and ,or ,not

s1=Users.select((Users.c.LASTNAME=='Smith') & (Users.c.FIRSTNAME=='John'))
s1=Users.select((Users.c.LASTNAME=='Smith') | (Users.c.FIRSTNAME=='John'))

s1=Users.select( ~(Users.c.LASTNAME=='Smith'))

like, endswith, startswith, between, in

s1=Users.select(Users.c.AGE.between(18,21))
s1=Users.select(Users.c.LASTNAME.like('%a'))
s1=Users.select(Users.c.FaxNumber.like('%'+str(kwargs['FaxNumber'])+'%'))
s1=Users.select(Users.c.LASTNAME.endswith('th'))
s1=Users.select(Users.c.LASTNAME.startswith('Mr'))
s1=Users.select(Users.c.LASTNAME.in_('Smith','Johnson'))

s1=Users.select(Users.c.LASTNAME.like('%'+kwargs['LASTNAME']+'%'))
s1=Users.select(Users.c.LASTNAME.like('%'+str(kwargs['USERID'])+'%'))

Advenced select()

different select: sqlalchemy.select()

import sqlalchemy
s2=sqlalchemy.select(Users.c.LASTNAME=='Smith')
s3=s2.execute()

s1=sqlalchemy.select( [Users.c.LAST,Users.c.FIRST,Users.c.Age],(Users.c.LASTNAME=='Smith')).execute()

group_by

x=sqlalchemy.select([Users.c.AGE], Users.c.LASTNAME=='Smith')
x2=x.execute()

x2=sqlalchemy.select([Users.c.AGE], group_by=[Users.c.AGE])
x2=x.execute()

x2=sqlalchemy.select([Users.c.AGE], Users.c.LASTNAME=='Smith',group_by=[Users.c.AGE])
x2=x.execute()