Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

2011-07-01

Compiling cx_Oracle for Python from Source on Solaris

We needed to use cx_Oracle on Solaris. cx_Oracle is a Python driver for Oracle. It is mentioned in Oracle FAQ.

In each version, the binaries for Windows and Enterprise Linux are released, but there are no pre-built binary packages for Solaris.

But you can easily download the source package and compile for your system. Its README file mentions that it compiles on Solaris and even they had being informed about successful compilation on Mac OS X.

This post assumes that Oracle was already installed on the system, as in my case.

I have downloaded the "Source Code only" package. For version 5.1, find it here. Download and extract the file, and open a terminal to the directory containing "setup.py".

As its README file says, use the following commands to build (become "root" first):
python setup.py build 
python setup.py install 

After the compilation, you need to do something unrecommended, setting "LD_LIBRARY_PATH", which is labeled as "bad".

Note that using Oracle requires you to use the account "oracle", so we will be using its ".profile" file.

If you "LD_LIBRARY_PATH" is not defined in the profile, you can add the following to the end of the file ".profile".
LD_LIBRARY_PATH=/usr/lib/:$ORACLE_HOME/lib32/ 
export LD_LIBRARY_PATH 

If you have already defined "LD_LIBRARY_PATH" you can add the following code instead:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib32/ 
export LD_LIBRARY_PATH 

If everything went well, you can use it in Python:
import cx_Oracle 
Note that the "oracle" user should be used, not "root".

I have accomplished this using Python 2.4.4 and cx_Oracle 5.1.

To see your Solaris version use the following command:
cat /etc/release 
# Solaris 10 5/09 
# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved. 
# Use is subject to license terms. 
# Assembled 30 March 2009 

2011-06-24

Standalone Usage of web2py's DAL, gluon

For a web project, I had to use the model of the MVC pattern outside the web server. I could do without it, but why to drop it if I could use the model without repeating myself? What I need, is to have a conventional web server serving a conventional web application. So far so good. But I also need to access the database from some other servers which has nothing to do with the web interface.

There are many many web frameworks existing for Python. Among them, both Django and web2py are innovative, great ones. Of course I am not a user of all the frameworks in Python, but these two are the ones that I am focusing on. Both Django and web2py are full-stack web frameworks, that means they provide all the layers of the MVC pattern without using extensions. They are both candidate for the job.

I had some constraints for this project.
  • The system should have an easy install. As I will use it in more than one server, I should not repeat myself in each update.
  • The model layer of the framework must run outside a web server.
  • Database Migration is preferred, but it should be controlled.
  • When I update the model, the others should not migrate, if they do, they would revert the database to the previous state. Only one migration is required. Somehow I must be able to stop them.
  • I should be able to reach my Python libraries installed in site-packages.
Both Django(provides an ORM) and web2py(provides a DAL) seems capable for my task. Django is more explicit, web2py is more automagic. Django supports database migrations using extensions like Django-South, web2py supports migrations by default.

I have attacked the problem using web2py.
Please note that this is not a introductory tutorial for web2py, if it were, would not be better than the official web2py book.

I am using Ubuntu 11.04 Natty amd_64, and the commands will be fully compatible with it, but there is no reason not to work for other operating systems too.

Downloading and installing web2py
This is a great advantage of web2py, it has no configuration nor installation. It works out of the box. I have downloaded the source distribution. And just unzipped it, that's it.

Adding the standalone module
Just created a directory, called "alone" in the web2py directory. This is not a "web2py application", actually it can be anywhere. Added a file "single_stuff.py" inside the directory. Overview of the directory and file structure, is this:


You know what, the DAL of web2py, it can handle all my needs and constraints:
  • The installation is.. There is not even an installation, this constraint is already done.
  • After adding the root folder of web2py to PYTHON_PATH, only some of the modules that are related with gluon can be imported. See how to do it in the source code. Done.
  • Migrations are automatic in web2py but we can fine tune it, we can disabled migrations for some objects. Done, very done.
  • The last constraint, accessing other modules, sure it works, we did nothing unconventional. Run it as "python single_stuff.py" as usual and do whatever you like.
web2py is now the choice for me in this project, for its simple yet powerful database abstraction layer, gluon.

Here is the source of the "single_stuff.py" with inline comments:

Or you can directly jump to see the code on Pastebin.
You can also download whole the code from Pastebin.

"""
An example to use only gluon, which is the name of
web2py's data abstraction layer.
"""

import os
import sys

# web2py is distributed and deployed with zero configuration.
# Let us follow the same approach.
# To do this, I have opened a directory called "alone" inside
# the web2py directory, next to applications.

# I want to distribute the whole web2py directory.
# So, I want to make sure that the gluon is automatically found.

sys.path.append("../")
# print sys.path

from gluon.sql import DAL, Field
from gluon.validators import *

# For simplicity, we will be using SQLite.
# First, determine the path for the database file.
# We are headed for portability, so let us open the database
# file in the same directory with this module.

module_path = os.path.abspath(os.path.dirname(__file__))
# print module_path # => /home/alex/Projects/web2py/alone

# This is only the file name:
db_name = "our_db.sqlite"

# The protocol and full path to our database file.
db = DAL('sqlite://' + db_name, folder=module_path)

# Define the table "genre", note that the field "id" is automatic.
db.define_table("genre",
        Field("name"))
db.genre.name.requires = IS_NOT_EMPTY()

# Define the table "band", note that the field "id" is automatic.
# band.genre_id references to genre.id field.
db.define_table("band",
        Field("name"),
        Field("origin"),
        Field("genre_id", db.genre))
db.band.name.requires = IS_NOT_EMPTY()
db.band.genre_id.requires = IS_IN_DB(db, db.genre.id, '%(name)s')
db.band.genre_id.writable = False
db.band.genre_id.readable = False

# Let us insert some data for table "genre".
# Each insert statement returns the unique_id.
id_rock = db.genre.insert(name="rock")
id_metal = db.genre.insert(name="metal")
id_grunge = db.genre.insert(name="grunge")  # we will use the ID.
id_jazz = db.genre.insert(name="jazz")

# The data will be stored only after a commit.
db.commit()

# We can also do a rollback, before a commit.
print db.genre.insert(name="banana")
# It will print 5 to the screen.
db.rollback()
# But it will not be stored in the database.

# Let us insert some data for table "band".
db.band.insert(name="Nirvana", origin="Aberdeen", genre_id=id_grunge)
# Do not forget to commit.
db.commit()

# A simple select.
for row in db(db.band.name == 'Nirvana').select():
    print row.name, row.origin
    #prints Nirvana Aberdeen

# We can also take the last query.
print db._lastsql
# It will print this:
# SELECT  band.id, band.name, band.origin, band.genre_id FROM band
# WHERE (band.name = 'Nirvana');

# We can use free, raw SQL queries too.
print db.executesql('SELECT * FROM genre;')
# [(1, u'rock'), (2, u'metal'), (3, u'grunge'), (4, u'jazz')] 


Exploring the database
If you want to look into the database using a graphical manager, you can use SQLite Database Browser, which can already be found in Ubuntu repositories, or SQLite Manager, which is a Mozilla Firefox extension and works anywhere.

Here are some screenshots after opening the database created and manipulated by "single_stuff.py":



As a result, web2py is too good to be true, but it is a fact that it is so.

2009-12-27

Using CPython modules from IronPython

I have IronPython 2.6 and Python 2.6.4 installed on a Windows box.

IronPython's interpreter ipy.exe is not installed on a directory on path, just unzipped in an arbitrary folder.
Python 2.6.4 is installed in C:\Python26 directory.

You can import pure CPython modules from IronPython as follows:

C:\Users\dude\Documents\SharpDevelop Projects\Faman5>ipy
IronPython 2.6 (2.6.10920.0) on .NET 2.0.50727.4927
Type "help", "copyright", "credits" or "license" for more information.
>>> # Try to import the os module.
>>> import os
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named os
>>> # OK, we are sure that the module is can not be imported.
>>> # Now we need to import the sys module to achive our goal.
>>> import sys
>>> # sys.path is the list of directories to look for when importing modules.
>>> sys.path
['.', '.', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5\\Lib', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5\\DLLs', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5']
>>> # Add the Cpython path to the sys.path as follows:
>>> sys.path.append("C:\Python26\Lib")
>>> sys.path
['.', '.', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5\\Lib', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5\\DLLs', 'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5', 'C:\\Python26\\Lib']
>>> # Now we are sure that 'C:\\Python26\\Lib' is added.
>>> # Let us try to import the os module again.
>>> import os
>>> os.getcwd()
'C:\\Users\\dude\\Documents\\SharpDevelop Projects\\Faman5'
>>> # Success!

2009-06-04

IronPython and C#, Hosting/Embedding, Part I

As IronPython improves, the way to embed it in other applications is changed too. It is constantly becoming easier and more general. When the C# 4.0 is released, it will be even more easier and useful.

I have written a simple hosting example for the current stable version. I have used IronPython 2.0.1, Visual Studio 2005 SP1, and .NET Framework 2.0 SP2. This example has not been tested with IronPython 2.6 Beta 1 nor IronPython 2.6 for .NET 4.0 Beta 1.

The example code can be seen as follows:

1  namespace IronPythonHostingExample
2  {
3      using System;
4      using IronPython.Hosting;
5      using Microsoft.Scripting.Hosting;
6
7      public class IronPythonStatementHostingExample
8      {
9          public static void ShowDemo()
10         {
11             ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(null);
12             ScriptRuntime runtime = new ScriptRuntime(setup);
13             ScriptEngine engine = Python.GetEngine(runtime);
14             ScriptScope scope = engine.CreateScope();
15             ScriptSource source;
16             string sourceCode = string.Empty;
17             sourceCode += "def factorial(n):" + Environment.NewLine;
18             sourceCode += "    f = 1" + Environment.NewLine;
19             sourceCode += "    i = 1" + Environment.NewLine;
20             sourceCode += "    if (i > n):" + Environment.NewLine;
21             sourceCode += "        return -1" + Environment.NewLine;
22             sourceCode += "    while (i < n):" + Environment.NewLine;
23             sourceCode += "        f = f * i" + Environment.NewLine;
24             sourceCode += "        i = i + 1" + Environment.NewLine;
25             sourceCode += "    return f" + Environment.NewLine;
26             sourceCode += "def add_two_numbers(n1, n2):" + Environment.NewLine;
27             sourceCode += "    return n1+n2" + Environment.NewLine;
28             sourceCode += "for i in range(5):" + Environment.NewLine;
29             sourceCode += "    print i" + Environment.NewLine;
30             sourceCode += "print factorial(5)" + Environment.NewLine;
31             sourceCode += "print factorial(-4)" + Environment.NewLine;
32             sourceCode += "print add_two_numbers(1, 2)" + Environment.NewLine;
33             source = scope.Engine.CreateScriptSourceFromString(sourceCode, Microsoft.Scripting.SourceCodeKind.Statements);
34             source.Execute(scope);
35         }
36     }
37 }



To compile it as a project, you need the following DLLs to be added to your project:
The DLL files can be found in the directory
"C:\Program Files\IronPython 2.0.1".