django连Oracle

 

http://aofengblog.blog.163.com/blog/static/6317021201157111336764/

Python - 使用cx_Oracle操作Oracle数据库 | Using the cx_Oracle to operate oracle database  

2011-06-07 15:06:07|  分类: Python |  标签:python  oracle  数据库  |字号 订阅

 
 
  文章声明

作者:傲风(aofengblog@163.com)       编写时间:2011年06月07日 

网址:http://aofengblog.blog.163.com

作者保留所有权利,转载请保留文章全部内容!

 

  python是一种动态语言,非常适合于处理数据逻辑,管理任务和程序的安装脚本。在Linux/Unix操作系统中,python已经默认安装。最近,花了一天多时间学习python,用于编写oracle数据库存储过程的自动化测试。下面是python操作Oracle的配置过程:

一、安装Oracle客户端| Install oracle client

Oracle提供了express版本的Oracle Client和Oracle Server,相对于企业版,express占用的资源更少,非常适合在开发环境使用。Oracle也提供了Ubuntu下的安装包,安装过程如下:
1、添加apt服务器。
1) 编辑/etc/apt/source.list,在末尾添加如下配置:
deb http://oss.oracle.com/debian unstable main non-free

2) 获取服务器资源的公钥。如果在代理环境下,使用wget获取有问题,可以用浏览器直接打开如下http地址,并将内容保存为一个文件。
wget http://oss.oracle.com/el4/RPM-GPG-KEY-oracle

3) 添加公钥到apt系统的密钥库中。
sudo apt-key add RPM-GPG-KEY-oracle

4) 更新软件包索引信息。
sudo apt-get update

2、安装Oracle client。
1) 执行如下命令,安装express 版本的Oracle client。
sudo apt-get install oracle-xe-client

2) 设置环境变量,编辑 ~/.profile,增加如下配置:
ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/client
export ORACLE_HOME

TNS_ADMIN=/usr/lib/oracle
export TNS_ADMIN

LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH

PATH=$PATH:$ORACLE_HOME
export PATH

3)使配置生效。执行如下命令:
source ~/.profile


二、安装cx_Oracle | Install cx_Oracle

1、在浏览器中打开如下http地址,下载cx_Oracle的源码:
http://prdownloads.sourceforge.net/cx-oracle/cx_Oracle-5.1.tar.gz?download

2、解压。
tar -zxvf cx_Oracle-5.1.tar.gz

3、进入解压后的目录,编译源代码。
python setup.py build
running build
running build_ext
building 'cx_Oracle' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/demo -I/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public -I/usr/include/python2.6 -c cx_Oracle.c -o build/temp.linux-i686-2.6-10g/cx_Oracle.o -DBUILD_VERSION=5.1
In file included from /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/oci.h:2655,
from cx_Oracle.c:10:/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/oci1.h:148: warning: function declaration isn’t a prototype In file included from /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/ociap.h:222,from /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/oci.h:2679,from cx_Oracle.c:10:
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:676: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2667: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2676: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2686: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2695: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2704: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2713: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2721: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2731: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2738: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/nzt.h:2746: warning: function declaration isn’t a prototype
In file included from /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/oci.h:2679, from cx_Oracle.c:10:
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/ociap.h:10069: warning: function declaration isn’t a prototype
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/ociap.h:10075: warning: function declaration isn’t a prototype
creating build/lib.linux-i686-2.6-10g
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-i686-2.6-10g/cx_Oracle.o -L/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/lib -L/usr/lib/oracle/xe/app/oracle/product/10.2.0/client -lclntsh -o build/lib.linux-i686-2.6-10g/cx_Oracle.so
python setup.py install
running install
running build
running build_ext
running install_lib
copying build/lib.linux-i686-2.6-10g/cx_Oracle.so -> /usr/local/lib/python2.6/dist-packages

三、编写第一个用cx_Oracle操作Oracle的代码段 | Hello cx_Oracle

1、编写cx_Oracle查询数据库的示例,其代码如下:
#! /usr/bin/python
#coding=UTF-8

import cx_Oracle

def hello():
    '''Hello cx_Oracle示例:
    
    1)打印数据库版本信息.
    2)查询表数据.'''
    
    conn = cx_Oracle.connect("codomain/codomain@10.3.3.92:1521/oracle1")
    cur = conn.cursor()
    try:
        print "Oracle Version:%s" % conn.version
        print "Table SUB_POLICY rows:"
        cur.execute('select * from SUB_POLICY')
        for row in cur:
            print row
    finally:
        cur.close()
        conn.close()

hello()
2、运行代码。
python ./DBOperate.py
结果如下:
Oracle Version:10.2.0.4.0
Table SUB_POLICY rows:
(4, 4, 1, 1, 2, 1, 1, None, None, None, None, None, None, 2, None, datetime.datetime(2011, 6, 1, 0, 0), 1, 0, None)
(1, 3, 1, 1, 1, 1, 1, None, None, None, None, None, None, 1, None, datetime.datetime(2011, 5, 31, 0, 0), 2, 0, None)
(2, 2, 2, 2, 2, 2, 2, None, None, None, None, None, None, 2, None, datetime.datetime(2011, 5, 31, 0, 0), 1, 0, None)
(3, 4, 3, 3, 3, 3, 3, None, None, None, None, None, None, 3, None, datetime.datetime(2011, 5, 25, 0, 0), 4, 0, None)

四、编译cx_Oracle常见问题的解决方法 | Solve problems

1、执行 python setup.py build 出现如下错误提示:
cx_Oracle.c:6: fatal error: Python.h: 没有那个文件或目录
compilation terminated.
error: command 'gcc' failed with exit status 1

Python - 使用cx_Oracle操作Oracle数据库 | Use cx_Oracle for oracle database operation - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来解决方法:
安装python dev library。

 

##########################################################

http://timchen119.blogspot.com/2007/07/tip-django-oracle-on-debian-linux.html

星期六, 七月 21, 2007

[tip] django + oracle on debian linux.

 

目前SVN裡最新版本django已經由官方直接支援oracle資料庫,
也因此我也花了點時間測試一下django跟oracle的配合.
用起來覺得還不錯, 所以跟大家分享一下我的簡易安裝心得.

首先我是直接安裝oracle 10g 的XE版本,
在debian linux上安裝oracle 10g xe其實很簡單, (我是用etch)
因為oracle連apt套件庫都幫你準備好了.

只要在你的sources.list加上這行:


deb http://oss.oracle.com/debian/ unstable main non-free

並安裝:

#wget http://oss.oracle.com/el4/RPM-GPG-KEY-oracle -O- | sudo apt-key add -
#apt-get update;apt-get install orcale-xe-universal

最後跑個/etc/init.d/oracle-xe configure即可作oracle的安裝設定.
如果想測試安裝oracle xe的結果可以連上Web的8080port看管理介面:
http://127.0.0.1:8080/apex/

這個版本的oracle除了有內定最大只能使用4G資料庫大小,1G Memory
跟只會使用單顆CPU的限制外,
並沒有限制其他特別嚴苛的條件, 連商業使用都在可允許的範圍.
而因為這個限制其實很夠用,且高階一點的機器可以跑個vserver還是memcache.
然後你要多跑幾個database也不在限制範圍內,
所以其實我個人覺得就是oracle資料庫大放送, 隨便你用.
再來這個版本又比我印象中的oracle好安裝的太多.
還送你一個web管理介面(而且oracle似乎有心要繼續維護10g XE,我安裝時有根據官網的說明順便升級到了目前最新的apex版本3.0.1),可以說是物超所值.

再來就是安裝python的oracle支援套件cx_oracle,
因為官方網站只有提供windows跟fedora的binary套件, 我就直接抓source回來安裝,

export ORACLE_HOME='/usr/lib/oracle/xe/app/oracle/product/10.2.0/server'
export LD_LIBRARY_PATH=$ORACLE_HOME/lib

python setup.py install


接下來當然就是安裝django的最新svn版本,
這點看官方網站的Installing the development version說明應該就很清楚了,
http://www.djangoproject.com/documentation/install/

安裝完之後其實就跟其他資料庫沒什麼太大的差異了,
就可以寫個小程式測試一下了,
不過我上次測試的時候遇到了一點小問題,
就是我在syncdb時出現了一個 
TypeError: descriptor 'upper' requires a 'str' object but received a 'unicode'
的錯誤訊息,
我推測應該是因為oracle這個branch剛好跟unicode這個branch同時進了svn trunk,
所以漏掉了這個,
可以暫時先依照我丟到http://code.djangoproject.com/ticket/4827的patch修正, 
不過我想下一版release的django應該就會修正這個問題才對.

總算,oracle成為
django除了mysql,postgresql,sqlite之外的第四個直接支援的database. 
也是第一個support的商業database. 
雖然我目前用不大到(postgres還是不錯滴), 不過還是可喜可賀. :)
 
 
 
http://www.oracle.com/technetwork/cn/articles/vasiliev-django-100817-zhs.html
 

在 Django 中构建 Oracle 数据库支持的 Web 应用程序


了解如何配置 Django 以便与 Oracle 数据库交互,并使用 ORM 进行数据库连接。

作者:Yuli Vasiliev

2009 年 8 月发布

产能在软件开发环境中意味着及时完成工作的能力。开发人员经常发现自己在重复执行相同的任务,这无疑会降低其产能。这是框架能够派上用场的地方:使用适当的框架,您可以将重点放在项目需求上,而不是处理低级、棘手的实施细节。

Django 是基于 Python 的 Web 应用程序框架,最初旨在简化数据库驱动的、面向新闻的 Web 应用程序的开发。其后,它已经发展成功能完备的 Web 框架,经常用来简化数据库支持的复杂 Web 应用程序的开发。

Django 的对象关系映射器 (ORM) 位于框架的中心,介于数据模型(您在 django.db.models.Model 类之上构建的 Python 类)和基础关系数据库对象之间。定义数据模型之后,您将能够通过映射到基础数据库中的对象的 Python 对象,来创建、检索、更新以及删除数据库数据。需要强调的是,除了 PostgreSQL、MySQL 和 SQLite 之外,Django 还正式支持 Oracle 数据库,可让您使用 ORM 特性访问和操作 Oracle 数据库数据。

安装 Django

如果您尚未安装 Django,现在可以进行安装。首先,确保您已安装 Python 2.3 或更高版本。此外,请务必安装 cx_Oracle 驱动程序(针对 Oracle 的 Python DB-API 实施),以便 Python 可与 Oracle 数据库交互。有关详细信息,您可以参阅 Przemyslaw Piotrowski 撰写的另一篇 OTN 文章“为 Python Server Pages 和 Oracle 构建快速 Web 开发环境”。然后,您可以从 Django Software Foundation 网站的 Download 页面获得 Django,地址为 http://www.djangoproject.com/download/。撰写本文时,最新的正式版本为 1.1。

安装非常简单。只需解压缩已下载的程序包,将目录更改到 Django 的解压缩目录,然后运行以下命令:

python setup.py install

上述命令将启动安装过程,此过程只需几秒。确保安装成功的最简单方法是通过 Python 交互式解释器。在交互式解释器会话中,只需输入以下命令:

import django

如果一切正常,您应该不会看到错误消息。

入门

假设您已安装 Django,现在可以尝试创建您的第一个 Django 项目,并在其中创建一个应用程序。

在 Django 中,项目包括特定网站的配置和应用程序。因此,单个项目实际上可能包括多个应用程序。然而,为了简单起见,在此创建的项目只包括一个应用程序。

首先,您可能要创建一个用于存储 Django 项目的文件夹,从操作系统提示符进入此文件夹,然后发出以下命令:

django-admin.py startproject myproj 

结果,应该显示 myproj 文件夹及其内含的以下四个文件:__init__.py、manage.py、settings.py 以及 urls.py。这四个文件的每一个都在项目中起着特定作用。

  • 包括 __init__.py 是为了让此目录成为 Python 程序包,以便您能够通过点符号引用项目的各部分;例如,myproj.settings。
  • manage.py 表示与上述 django-admin.py 提供相同命令但旨在用于此特定项目的命令行实用程序。
  • settings.py 是包含项目设置的配置文件。在此,您可以指定数据库连接信息、时区和语言代码、有关项目中所安装的应用程序的信息,以及一些其他设置。
  • urls.py 又称为 URLconf,是包含将 URL 模式映射到 Python 回调函数的 Python 代码的配置文件。

您可以看到,即使 Django 项目的配置文件也是以 Python 源代码文件的形式提供。此方法被证明很有优势,因为它使您能够动态指定设置和/或从其他配置文件中导入设置。

现在您已创建项目,可以继续下一环节,在此项目内创建一个应用程序。为此,进入先前由 django-admin.py 生成的 myproj 文件夹,并发出以下命令:

manage.py startapp myapp

在 Linux 上,您可能需要发出:

chmod +x manage.py
./manage.py startapp myapp

上述命令应该生成文件夹 myapp 及其内含的以下四个文件:__init__.py、models.py、views.py 以及 tests.py。同样,__init__.py 用于使此目录成为 Python 程序包。Tests.py 可用于为应用程序构建测试套件。此外,您将使用其余的两个文件分别定义应用程序的模型和视图:

  • models.py 用于包含模型(您在 django.db.models.Model 类之上构建的 Python 类),其中每个模型都映射到一个数据库表。
  • views.py 用于包含视图(Python 函数),其中每个视图或者返回 HttpResponse 对象(内容将显示在所请求页面上),或者引发 HTTP 异常。

下一步是将新创建的应用程序与项目相关联。为此,您需要编辑 myproj 文件夹中的 settings.py 文件,将字符串“myproj.myapp”追加到 INSTALLED_APPS 字节组中,如下所示:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'myproj.myapp'
)

您已完成了应用程序主干的构建。然而,在可以查看应用程序是否正常工作之前,需要执行一些额外步骤。当然,这些步骤可能会有所不同,具体取决于您希望应用程序执行的操作。例如,如果您要构建不与数据库交互的简单应用程序,则不需要将数据库信息放在 settings.py 配置文件以及设计数据模型中。但在大多数情况下,您至少需要执行以下五个步骤:

  • 在 settings.py 中指定数据库信息
  • 创建模型
  • 创建模板
  • 创建视图
  • 在 urls.py 中配置 URL 模式

在继续上述步骤之前,让我们看一下 Django 应用程序的高级视图,以便您可以更好地了解 Django 中的组件如何工作。下图示意性地显示了 Django 应用程序如何工作以满足用户请求。

根据此图中的图示,工作方式如下:

  1. 用户输入支持 Django 的站点的 URL 或在此站点的已加载页面上执行操作,从而将请求发送到托管此站点的 Web 服务器。
  2. Django 的 URL 调度程序遍历 urls.py 文件中的 URL 模式,并选择第一个与用户请求的 URL 匹配的模式,然后调用与所发现模式相关联的视图(Python 回调函数)。
  3. 视图使用数据模型获得数据库数据,然后加载指定模板(已嵌入特殊模板标记的 HTML 页面;它类似于 Java 中的 JavaServer Page),并向其传递上下文(包括映射到模板变量名称的已获得数据)。
  4. 最后,视图返回由已呈现模板填充的 HttpResponse 对象,如果出现错误,则返回 HTTP 异常。

您可以看到,Django 基于将 Web 应用程序逻辑分为模型、视图和模板的概念,因此有效地将业务逻辑和展示分离开来。通常,这类似于当今许多其他 Web 框架中使用的模型-视图-控制器 (MVC) 范例。然而,在 Django 中,视图更像控制器,介于模型和模板之间。而 Django 模板更接近于 MVC 视图,因为这些模板负责使用从模型中获得的数据生成适当的用户界面。

现在您已掌握 Django 的概念,让我们继续在本部分开头启动的项目,构建一个与 Oracle 数据库交互的简单应用程序。

配置 Django 以便与 Oracle 数据库交互

您必须先告诉 Django 如何连接到数据库,才能利用 Django 的数据库相关特性。您可以通过在项目的 settings.py 配置文件中配置数据库相关设置来执行此操作。对于在上一部分开头创建的项目,您需要编辑 django-admin.py 生成的 myproj 目录中的 settings.py。

在文本编辑器中打开 settings.py 文件,并根据您的数据库编辑与数据库相关的设置。例如,您可能按如下方式编辑它们:

DATABASE_ENGINE = 'oracle' 
DATABASE_NAME = 'XE' 
DATABASE_USER = 'hr' 
DATABASE_PASSWORD = 'hr' 
DATABASE_HOST = 'localhost' 
DATABASE_PORT = '1521'

上述方式假设您在数据库中安装了 HR 演示模式并解除了锁定。然而,在实际项目中,您很可能会使用针对特定应用程序设计的自定义模式。需要注意的是,Django 可以省去您自己创建基础表的麻烦。完成数据模型的构建之后,您可以运行 manage.py syncdb 命令以自动创建数据库表 — 针对 models.py 文件中的每个数据模型创建一个数据库表。但为了简单起见,本文中的示例将使用 HR 演示模式中已经存在的表。

现在您已指示 Django 与特定 Oracle 数据库交互,可以继续构建数据模型。

与模型的对象关系映射

如前所述,Django 支持与模型的对象关系映射,其中每个模型映射到单个数据库表,并表示子类为 django.db.models.Model 标准类的 Python 类。

以下示例说明如何针对现有表定义模型。在此示例中,您将使用 HR 的 employees 表,仅针对此表的选定字段定义模型字段。在 myproj/myapp 目录中打开 models.py 文件并进行编辑,添加 employees 类,如下所示:

from django.db import models


# Create your models here.
                 
class employees(models.Model):
    employee_id = models.IntegerField(primary_key=True)
    first_name = models.CharField(max_length=20, null = True)
    last_name = models.CharField(max_length=25)
    email = models.CharField(max_length=25)
    class Meta:
         db_table = "employees"

请注意,此处使用了一些模型字段选项。通过设置 primary_key = True,可显式指定此字段是模型的主键。max_length 是 CharField 这一字符串字段所需的参数。如果将可选的 null 参数设置为 True,即表示告诉 Django 将空值作为 NULL 保存到数据库中。默认情况下,此参数设置为 False。要查看字段选项和字段类型的完整列表,您可以参阅 Django 文档中的 Model 字段参考页面。

在上述示例中,另一个需要注意的事项是类 Meta 的使用,您可以通过此类为模型提供元数据选项。在此特定示例中,您使用 db_table 选项显式指定模型要映射到的表的名称。实际上,默认情况下,Django 假设表的名称由模型类的名称和应用程序名称组成(通过下划线 (_) 符号分隔)。因此,在此特定示例中,Django 将查找名为 myapp_employees 的表。当然,db_table 并不是您可用于模型内部类 Meta 的唯一选项。您可以在 Django 文档的 Model Meta 选项页面上查看可用的 Meta 选项列表。

此处讨论的示例很简单,因为它仅显示到单个数据库表的映射。但实际上,您通常必须处理一组通过外键约束相互关联的基础数据库表。为了解决此问题,Django 提供了 ForeignKey 字段类型,可让您定义表示多对一关系的模型字段。

幸运的是,HR 演示模式仅包含一组通过外键约束相互关联的表。例如,您可能选择 departments 表(其 manager_id 字段是 employees 表中 employee_id 的外键),并定义以下模型(将其添加到 models.py 文件中):

class departments(models.Model):
    department_id = models.IntegerField(primary_key=True)
    department_name = models.CharField(max_length=30)
    manager = models.ForeignKey(employees, null = True)
    class Meta:
         db_table = "departments"

看一下上述模型定义,您可能已经注意到,它针对外键模型字段使用名称 manager,而不是实际在 departments 表中使用的 manager_id。实际上,在模型中使用的 manager 字段引用相应的 employees 对象,而非此对象的 employee_id 字段。当外键字段名称要引用基础表中的相应列时,Django 会隐式地将 _id 追加到此名称中。然而,在某些情况下,表中外键字段的名称结尾可能不包含 _id。如果是这种情况,您可以使用外键模型字段的 db_column 参数显式指定表列名称。虽然在此特定示例中无需如此,但您可以使用以下语法在 departments 表中显式指定外键列的名称:

manager = models.ForeignKey(employees, db_column = 'manager_id', null = True)

除了上述通过 ForeignKey 定义的多对一关系之外,Django 还支持一对一和多对多关系,您可以在模型中分别通过 OneToOneField 和 ManyToManyField 字段来定义。

使用数据库抽象 API

完成模型构建之后,您可以继续下一环节,构建将使用这些模型的视图。您可以在此使用 Django 数据库抽象 API 创建、检索、更新以及删除映射到基础数据库中的对象的 Python 对象(模型)。

让我们借助在上一部分中创建的模型,创建一个将从 employees 和 departments 数据库表中获取数据的简单视图。在 myproj/myapp 目录中,打开 views.py 文件并进行编辑,如下所示:

# Create your views here.


from django.template import Context, loader
from django.http import HttpResponse
from myproj.myapp.models import employees, departments


def index(request):
    department_list = departments.objects.exclude(manager__employee_id__exact = None).order_by('manager__employee_id')
    tmpl = loader.get_template("index.html")
    cont = Context({'departments': department_list})
    return HttpResponse(tmpl.render(cont))

在此,您添加了一个简单视图(实际上是一个名为 index 的函数),它将填充部门列表 (department_list),其中仅包括那些具有经理的部门(这意味着,必须填写基础表中的 manager_id 字段)。然后,该视图加载 index.html 模板(将在“创建表示层”部分中讨论),并向其传递 department_list 以便呈现。最后,向 Django 返回包含 HttpResponse 对象的已呈现页面。

在此,最有趣的部分是从 departments 模型中获取数据。请注意 departments 模型类的 objects 属性的用法。通过此属性,您可以访问 models.Manager 对象(不要将它与 departments 模型中定义的 manager 字段混淆)。models.Manager 对象会附加到模型对象中,提供可让您在模型的基础表中查询数据的方法。这些方法将返回一个 QuerySet 对象,其中包含以模型对象的形式检索的数据库数据。QuerySet 对象还提供一组有用的方法,允许您进一步处理返回的模型对象。需要注意的是,一些 QuerySet 方法会返回新的 QuerySet 对象,而其他方法仅对现有 QuerySet 进行求值,然后根据此求值返回一些信息。可以在 Django 文档的 QuerySet API 参考页面上找到完整的 QuerySet 方法列表。

在此讨论的示例中,models.Manager 的 exclude 方法用于将检索的 departments 对象仅限于那些具有相关 employees 对象的对象。然后,QuerySet 的 order_by 方法返回按 departments.manager.employee_id 字段排序的新 QuerySet 对象。它类似于以下 Oracle SQL 查询:

SELECT * FROM departments WHERE manager_id IS NOT NULL ORDER BY manager_id;

除了此处使用的 exclude 方法之外,您还可以通过 objects 属性调用其他三种方法来查询模型数据。清单如下:

  • all — 返回包含所有从模型基础表中获取的模型对象的 QuerySet。
  • filter — 返回仅包含那些与指定条件匹配的模型对象的 QuerySet。
  • exclude — 返回包含与指定条件不匹配的模型对象的 QuerySet。
  • get — 返回与指定条件匹配的单个模型对象。

由于 employees HR 表中的员工 ID 从 100 开始,因此在上一示例中,您可以用 filter 替代 exclude 以便使用数据填充 department_list,如下所示:

department_list = departments.objects.filter(manager__employee_id__gte = 100).order_by('manager__employee_id')

与原始版本一样,要考虑到在 departments 和 employees 模型之间定义的多对一关系(之讨论过),在此情况下,SQL 对应物可能基于 departments 表查询,如下所示:

SELECT * FROM departments WHERE manager_id >= 100 ORDER BY manager_id;

此处讨论的所有模型查询方法(all 方法除外)都采用查找参数以缩小检索模型对象的结果集。因此,在上述示例中,您结合使用以下查找参数和 filter 方法来查询 departments 对象:

manager__employee_id__gte = 100

您可能已经猜到,上述查找参数适合以下模式:field__subfield__lookuptype=value,其中参数由双下划线分隔的关键字组成。在此,manager 是引用 employees 对象的 departments 模型的字段。而 employee_id 是 employees 模型的字段。gte 是表示大于或等于的标准字段查找。可以在此示例中使用上述组合,因为 departments 和 employees 模型通过多对一关系关联。然而,当查询非相关数据时,您应使用以下模式:field__lookuptype=value。例如,为了获得 employee_id 为 100 的 employees 对象,您可以按如下方式查询 employees 模型:

emp = employees.objects.get(employee_id__exact = 100)

实际上,您可能需要发出包含复杂 select 列表和/或复杂 WHERE 子句的查询。例如,您要根据以下查询获得 employees 对象:

SELECT employees.*, (email||'@company.com') as email_address FROM employees;

您如何告诉 Django 向依赖 employees 模型的查询的 select 列表中添加另一个字段?这就是 QuerySet 方法 extra 能够派上用场的地方。

employee_list = employees.objects.all().extra(select={'email_address': "(email||'@company.com')"})

结果,Django 将自动向此处检索的每个 employees 对象添加 extra 属性 email_address。

当然,您不仅可以使用 extra 方法增强 QuerySet 隐式生成的查询的 select 列表。您还可以指定显式 WHERE 子句并向查询的 FROM 子句添加表,以及提供要绑定到 WHERE 子句中指定的相应占位符的动态参数。以下是您可以传递到 extra 方法的参数列表:

  • select — 将额外字段添加到 QuerySet 隐式生成的查询的 select 列表
  • where — 在 QuerySet 查询中指定显式 WHERE 子句
  • tables — 在 QuerySet 查询的 from 列表中包括其他表
  • order_by — 按照通过 select 或 tables 参数添加的字段对 QuerySet 进行排序
  • params — 传入将安全绑定到 WHERE 子句中指定的占位符的动态参数

到目前为止,您已了解说明如何使用 Django 数据库抽象 API 查询基础数据库数据的示例。然而,除了查询之外,您还可以使用 API 创建、更新以及删除数据库数据。

以下代码段说明如何使用此处讨论的 employees 和 departments 模型在 departments 数据库表中创建新的记录:

emp = employees.objects.get(employee_id__exact=100)
new_dept = departments(department_id = 1000, department_name = 'test', manager = emp)
new_dept.save()

结果,应该在 departments 表中显示新行。需要注意的是,model.save 方法还可用于更新现有行:

dept = departments.objects.get(department_id__exact=1000)
dept.department_name = 'new name'
dept.save()

最后,要删除行,请使用 model.delete:

dept = departments.objects.get(department_id__exact=1000)
dept.delete()

事务管理

默认情况下,Django 使用自动提交事务模式。这意味着,它可立即提交通过数据更改模型方法(例如上一部分中的 model.save 和 model.delete)进行的更改。但是,您可以使用 django.db.transaction 模块提供的事务修饰程序,针对特定视图函数更改此默认行为。您具有以下三个选项:

  • @transaction.autocommit(默认)
  • @transaction.commit_on_success
  • @transaction.commit_manually

例如,您可能指示 Django 在视图函数内使用单个事务,并在最后仅当此函数成功返回时提交,如下所示:

from django.http import HttpResponse
from myproj.myapp.models import employees, departments
from django.http import Http404
from django.db import transaction


@transaction.commit_on_success
def newdept(request, emp_id, dept_id, dept_name):
    try:
      new_dept = departments(department_id = dept_id, department_name = dept_name, manager = None)
      new_dept.save()
      emp = employees.objects.get(employee_id__exact = emp_id)
      new_dept.manager = emp
      new_dept.save()
    except employees.DoesNotExist:
      raise Http404
    return HttpResponse("The %s department record has been inserted." %dept_name)

上述 newdept 视图函数仅当成功返回时才自动提交在其内执行的所有操作。如果引发异常,则回滚所有未定更改。但是,如果您删除 newdept 视图函数前面的修饰词或者用 @transaction.autocommit 替代此修饰词,事务行为将发生更改。如果无法找到指定员工,仍将产生 HTTP 404 异常。但此时,第一个 new_dept.save 进行的更改将立即提交到数据库,产生 manager_id 字段为空的部门记录。

需要注意的是,上面列出的代码可以通过 django.shortcuts 模块中定义的 get_object_or_404 函数大大简化。修改如下所示:

...
from django.shortcuts import get_object_or_404 


@transaction.commit_on_success
def newdept(request, emp_id, dept_name, dept_id):
    new_dept = departments(department_id = dept_id, department_name = dept_name, manager = None)
    new_dept.save()
    emp = get_object_or_404(employees, employee_id__exact = emp_id)
    new_dept.manager = emp
    new_dept.save()
    return HttpResponse("The %s department record has been inserted." %dept_name )

然而,如果您已选择 commit_manually 修饰程序,则不会选择上述语法。在这种情况下,您需要分别使用 transaction.commit 或 transaction.rollback 显式提交或回滚事务。因此,try-except 语法似乎更适用于这种情况:

...
from django.db import transaction
...
@transaction.commit_manually
def newdept(request, emp_id, dept_id, dept_name):
    try:
      new_dept = departments(department_id = dept_id, department_name = dept_name, manager = None)
      new_dept.save()
      emp = employees.objects.get(employee_id__exact = emp_id)
      new_dept.manager = emp
      new_dept.save()
    except employees.DoesNotExist:
      transaction.rollback()
      raise Http404
    else:
      transaction.commit()
    return HttpResponse("The %s department record has been inserted." %dept_name)

将上述 newdept 视图添加到 myproj/myapp/views.py 中。

创建表示层

如上所述,Django 模板旨在使用 django.template.Context 对象在视图中显示传递给它们的信息。回到在前面的“使用数据库抽象 API”部分中讨论的 index 视图函数,让我们创建在此视图中使用的模板 index.html。

首先,在 myapp 目录内创建一个名为 templates 的目录。默认情况下,这是 Django 查找模板的目录。然后,在 myapp/templates 目录内创建 index.html,并将以下代码插入文件中:

<h1>Managers of departments</h1> 
<table border = 1px cellpadding="3" style="font-family:Arial"> 
<tr> 
<th>empid</th> 
<th>first name</th> 
<th>first name</th> 
<th>email</th> 
<th>department name</th> 
</tr> 
{% for department in departments %} 
<tr> 
<td>{{department.manager.employee_id}}</td> 
<td>{{department.manager.first_name}}</td> 
<td>{{department.manager.last_name}}</td> 
<td>{{department.manager.email}}</td> 
<td>{{department.department_name}}</td> 
</tr> 
{% endfor %} 
</table>

模板中的代码非常简单。您使用标准 HTML 标记定义标题和表元素,嵌入 Django 的模板语言元素,这些语言元素的变量标记位于双花括号 {{ ..}} 中,而块标记位于 {% ..%} 对中。要了解有关 Django 模板语言的更多信息,您可以参阅 Django 文档中的“The Django template language”页面。

URL 调度

对于此处讨论的 Django 应用程序,最后一个难题是 URLconf,它应该包含传入请求与视图函数匹配的 URL 模式。虽然您可以完全在项目级别定义这些模式,但将应用程序的 URL 从项目的配置中分离出来被认为是个较好的做法。因此,按如下方式编辑 myproj 目录中的 urls.py 文件:

...
urlpatterns = patterns('',

...

    url(r'^myapp/', include('myproj.myapp.urls')),
)

然后,在 myapp 目录中创建 urls.py 文件,并将以下代码插入其中:

from django.conf.urls.defaults import * 
from myapp.views import index, newdept

urlpatterns = patterns('', 
url(r'^(?P<emp_id>\d+)/(?P<dept_name>\w+)/(?P<dept_id>\d+)/$' , newdept), 
url(r'^$', index), 
)

您可能已经猜到,第一种模式旨在处理向“事务管理”部分中讨论的 newdept 视图发出的请求,第二种模式用于向 index 视图发出的请求。

使用 Django 开发 Web 服务器

现在该测试您刚构建的 Django 应用程序了。为此,您可以使用 Django 的内置开发 Web 服务器。首先,从操作系统提示符进入 myproj 目录,并发出以下命令:

manage.py runserver

结果,您应该看到一些告知您开发服务器正在运行的输出行,以及此服务器所在的地址(默认情况下,应该为 http://127.0.0.1:8000/)。剩下的就是将您的浏览器指向 http://127.0.0.1:8000/myapp/。结果应该如下图所示:

要测试 newdept 视图,您可以在 Web 浏览器中输入以下 url:http://localhost:8000/myapp/100/test/1000/。这应该将新记录插入 departments 表中,此记录的 department_id 为 1000,department_name 为 test,manager_id 为 100。


将 Django 用于 Apache

Django 的内置开发 Web 服务器仅适用于测试,这意味着它并不是生产服务器。如果要将它用于生产,您需要慎重考虑。

您可以通过 mod_python 模块(用于在 Apache 内嵌入 Python)将 Django 部署到 Apache。因此,首先确保您已将 mod_python 模块安装到 Apache 服务器上(可以在 此处找到详细信息)。然后,您可以将以下 Location 块添加到 Apache 的 httpd.conf 配置文件中(在 PythonPath 中使用实际路径):

< Location "/myapp/">
    SetHandler python-program
    PythonPath "['/home/user/myprojects', '/home/user/myprojects/myproj'] + sys.path"
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE myproj.settings
    PythonDebug On
< /Location>

重新启动 Apache 之后,您就可以测试应用程序了。如果您的 Apache 服务器在 localhost 上运行,您可以将浏览器指向 http://localhost/myapp/ 以测试 index 视图,指向 http://localhost/myapp/100/test/1000/ 以查看 newdept 是否正常工作。

结论

正如您在本文中了解的那样,Django 是一个功能强大的 Web 框架,可让您迅速创建数据库驱动的 Web 应用程序。您还可以轻而易举地将 Django 连接到 Oracle 数据库。此外,Django 还具有绝佳的 ORM 特性。


Yuli Vasiliev 是一名软件开发人员、自由撰稿人和顾问,目前专攻开源开发、Java 技术、数据库和面向服务的体系结构 (SOA)。他撰写了 Beginning Database-Driven Application Development in Java EE:Using GlassFish(Apress,2008)和 PHP Oracle Web Development(Packt,2007)。
 
 
https://docs.djangoproject.com/en/dev/ref/databases/

Oracle notes

Django supports Oracle Database Server versions 9i and higher. Oracle version 10g or later is required to use Django's regexand iregex query operators. You will also need at least version 4.3.1 of the cx_Oracle Python driver.

Note that due to a Unicode-corruption bug in cx_Oracle 5.0, that version of the driver should not be used with Django;cx_Oracle 5.0.1 resolved this issue, so if you'd like to use a more recent cx_Oracle, use version 5.0.1.

cx_Oracle 5.0.1 or greater can optionally be compiled with the WITH_UNICODE environment variable. This is recommended but not required.

In order for the python manage.py syncdb command to work, your Oracle database user must have privileges to run the following commands:

  • CREATE TABLE
  • CREATE SEQUENCE
  • CREATE PROCEDURE
  • CREATE TRIGGER

To run Django's test suite, the user needs these additional privileges:

  • CREATE USER
  • DROP USER
  • CREATE TABLESPACE
  • DROP TABLESPACE
  • CONNECT WITH ADMIN OPTION
  • RESOURCE WITH ADMIN OPTION

Connecting to the database

Your Django settings.py file should look something like this for Oracle:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': '',
        'PORT': '',
    }
}

If you don't use a tnsnames.ora file or a similar naming method that recognizes the SID ("xe" in this example), then fill in bothHOST and PORT like so:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': 'dbprod01ned.mycompany.com',
        'PORT': '1540',
    }
}

You should supply both HOST and PORT, or leave both as empty strings.

Threaded option

If you plan to run Django in a multithreaded environment (e.g. Apache in Windows using the default MPM module), then youmust set the threaded option of your Oracle database configuration to True:

'OPTIONS': {
    'threaded': True,
},

Failure to do this may result in crashes and other odd behavior.

INSERT ... RETURNING INTO

By default, the Oracle backend uses a RETURNING INTO clause to efficiently retrieve the value of an AutoField when inserting new rows. This behavior may result in a DatabaseError in certain unusual setups, such as when inserting into a remote table, or into a view with an INSTEAD OF trigger. The RETURNING INTO clause can be disabled by setting the use_returning_into option of the database configuration to False:

'OPTIONS': {
    'use_returning_into': False,
},

In this case, the Oracle backend will use a separate SELECT query to retrieve AutoField values.

Naming issues

Oracle imposes a name length limit of 30 characters. To accommodate this, the backend truncates database identifiers to fit, replacing the final four characters of the truncated name with a repeatable MD5 hash value.

When running syncdb, an ORA-06552 error may be encountered if certain Oracle keywords are used as the name of a model field or the value of a db_column option. Django quotes all identifiers used in queries to prevent most such problems, but this error can still occur when an Oracle datatype is used as a column name. In particular, take care to avoid using the namesdatetimestampnumber or float as a field name.

NULL and empty strings

Django generally prefers to use the empty string ('') rather than NULL, but Oracle treats both identically. To get around this, the Oracle backend ignores an explicit null option on fields that have the empty string as a possible value and generates DDL as if null=True. When fetching from the database, it is assumed that a NULL value in one of these fields really means the empty string, and the data is silently converted to reflect this assumption.

TextField limitations

The Oracle backend stores TextFields as NCLOB columns. Oracle imposes some limitations on the usage of such LOB columns in general:

  • LOB columns may not be used as primary keys.
  • LOB columns may not be used in indexes.
  • LOB columns may not be used in a SELECT DISTINCT list. This means that attempting to use the QuerySet.distinct method on a model that includes TextField columns will result in an error when run against Oracle. As a workaround, use theQuerySet.defer method in conjunction with distinct() to prevent TextField columns from being included in the SELECT DISTINCTlist.

Django是简介:

    Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的设计模式,即模型M,模版T和视图控制器V。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。
    Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don’t Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。更多信息在这里

Django安装

    安装Django之间你必须安装python,到python.org(千万别到python.com上,别怪我没有告诉你)上去下载2.3以上,3.0以下的版本(3.x的版本不向下兼容,目前django还不支持)。到http://www.djangoproject.com/download/下载最新的django1.0.2的gz包,
在linux下的安装为:
    1:tar xzvf Django-1.0.2-final.tar.gz
    2:cd Django-1.0.2-final
    3:sudo python setup.py install
在windows下面的安装方式为:
    1:进入命令行;转到django的解压缩目录
    2:输入:C:\Python25\python.exe setup.py install 就可以了,这里的python.exe是自己的的python在windows下的安装目录。

开发前准备工作

    1:django支持的数据库
    在web开发之旅中,摆脱数据库总是不太现实,所以需要了解一下django支持的数据库,目前django支持5中数据库:OracleMySQL ,PostgreSQL SQLite 3 ,Microsoft SQL Server 
    Oracle和Django的结合
    目前支持oracle 9i以上的版本,你需要到http://cx-oracle.sourceforge.net/下载cx-oracle包来提供相关的支持。
    Mysql和Django的结合
    支持Mysql4.0以上的版本,需要到http://sourceforge.net/projects/mysql-python下载mysql-python包。
    其他数据库工作中很少关注,如果想继续关注请google一下。
2:web服务器的安装
    (1)到www.modpython.org下载mod_python包,安装中会自动找到你的python安装目录和apache的安装目录,如果提示没有找到,就需要你选择一下相关的安装目录,如果错误会自动退出安装。
    (2)在apache的httpd.conf中添加相关的配置:
   在<IfModule alias_module></IfModule> 中间添加相关的配置,注意你的apache的版本号对应的相关的配置。
    LoadModule python_module modules/mod_python.so
    <Directory "E:/python/web">
        Options FollowSymLinks
        AllowOverride None
        Order allow,deny
        allow from all
        Satisfy all
        AddHandler mod_python .py
        PythonHandler test
        PythonDebug On
    </Directory>
    (3)测试一下你的服务器,在目录E:/python/web下面新建test.py,内容如下:
    from mod_python import apache

1
2
3
def handler(req):
  req.write(&quot;Hello World!&quot;)
  return apache.OK

    启动apache服务器,在浏览器中输入http://localhost/python/test.py,现实Hello World!则代表服务器启动了。

 

开始django之旅

    (1)到django的安装目录(C:\Python25\Lib\site-packages\django\bin),执行C:/Python25/python.exe django-admin.py startproject mydjango 然后在安装目录下面会有4个文件,分别是:__init__.py (可以向Python编译器表明当前文件夹下的内容是Python工程模块) ;manage.py (一个命令行工具,可以让你以多种方式与Django项目交互);setting.py (Django项目的配置 );urls.py (负责配置URL的地址映射以及管理URL的地址格式 )Python代码不要放在document root下 ,因为这样做别人可以从Web看到你的代码;把代码放在document root以外的目录,如/opt/mydjango。
    (2)在命令模式下执行:
        C:\Python25\Lib\site-packages\django\bin>cd mydjango
        C:\Python25\Lib\site-packages\django\bin\mydjango>C:/Python25/python.exe manage.py runserver
        Validating models…
        0 errors found
        Django version 1.0.2 final, using settings ‘mydjango.settings’
        Development server is running at http://127.0.0.1:8000/
        Quit the server with CTRL-BREAK.
    在浏览器中看到相关的内容,就说明启动了Django应用服务器,如果你的代码有改动,它自动reload,不需要重启项目。默认情况下runserver命令启动服务器的端口为8000,只监听本地连接 
    如果你希望改变端口,增加一个命令行参数即可:
        C:/Python25/python.exe manage.py runserver 8080 
    你也可以改变服务器监听的IP地址:
        C:/Python25/python.exe manage.py runserver 0.0.0.0:8080
    后面你就可以自己写python的代码。

推荐2本django的电子书籍

    1:django step by step
    2:The Django Book      中文版翻译在这里
    如果你python还没有学习的话,请买本《python核心编程第二版》读读吧!

配置过程中可能的问题

1:在windows的命令模式下执行 python 报错:
计算机的属性》高级》计算机环境变量》path中添加C:\Python25(python安装目录)
2:403错误,查找apache下面的error日志:
client denied by server configuration
apache2.0和2.2的配置文件不一样。
2.0:
Options FollowSymLinks
AllowOverride None 
2.2:
Options FollowSymLinks
AllowOverride None
Order allow,deny
Deny from all   这个地方需要修改为allow from all
Satisfy all

 

 

 

http://bigzhu.is-programmer.com/posts/20388.html

 

http://www.python.net/crew/atuining/cx_Oracle/下载适配器cx_Oracle

 

打开settings.py文件,配置oracle连接:

 

DATABASE_ENGINE = 'oracle' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
DATABASE_NAME = 'bill' # Or path to database file if using sqlite3.
DATABASE_USER = 'acct' # Not used with sqlite3.
DATABASE_PASSWORD = '' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = '1521' # Set to empty string for default. Not used with sqlite3.

 

DATABASE_ENGINE 填入数据库驱动,这里自然填入oracle

 

DATABASE_NAME 填入sid,可以查看本机的tnsnames.ora是如何配置的

 

DATABASE_USER 数据库用户

 

DATABASE_PASSWORD 用户密码

 

DATABASE_HOST 直接填入ip地址就可以

 

DATABASE_PORT oracle服务的端口号

 

配置完毕后,保存,开始测试:

 

进入django的project目录

 

python manage.py shell

 

进入使用了对应settings的命令行.

 

输入:

 

>>> from django.db import connection
>>> cursor = connection.cursor()

没有任何报错就说明成功了.

 

 

 

posted @ 2012-05-23 14:38  陳聽溪  阅读(2656)  评论(0编辑  收藏  举报