{ "info": { "author": "Nuuk Zweiundvierzig", "author_email": "nuuk42@yahoo.com", "bugtrack_url": null, "classifiers": [], "description": "cy_Oracle\n=========\n\ncy_Oracle is a simple Python module that improves the handling of\nOracle object types compared to cx_Oracle.\ncy_Oracle supports a central declaration of a mapping between\nPython classes and Oracle object types. This mapping can be\nused in DML (SELECT, UPDATE, INSERT) as well as with PL/SQL\nfunctions and procedures. Details are described in the online help\nfor the function \"addTypemap\".\n\n>>> import cy_Oracle\n>>> help(cy_Oracle.OracleDB.addTypemap)\n\nThe entry point for the client is the class cy_Oracle.OracleDB.\nHere you define the connection parameter to the Oracle database\n(User, Password, URL). \n\n>>> import cy_Oracle\n>>> help(cy_Oracle.OracleDB) for details.\n\nThe class cy_Oracle.Connection derives from cx_Oracle.Connection.\nIt does not add any new methods, but override the method \"cursor()\".\nHere we return an object of the class cy_Oracle.Cursor. \n\n>>> import cy_Oracle\n>>> help(cy_Oracle.Connection.cursor) for details.\n\nThe class cy_Oracle.Cursor derives from cx_Oracle.Cursor.\nHere we setup the input and output handlers to map between\nOracle object types and Python classes. \n\n>>> import cy_Oracle\n>>> help(cy_Oracle.Cursor) for details.\n\nExample 1\n---------\n\nThis 'Hello World' example for the module cy_Oracle will \nlist the names and the creation date of objects in the \ndatabase schema \"book\"::\n\n 1 from cy_Oracle import OracleDB\n 2 # setup the DB connection\n 3 myDB = OracleDB(user='book', password='book', databaseURL='bookdb')\n 4 # connect to DB\n 5 con = myDB.connect()\n 6 # select some data from the view 'USER_OBJECTS'\n 7 cur = con.cursor()\n 8 cur.execute('SELECT object_name, created from user_objects')\n 9 # loop the result\n 10 for row in cur:\n 11 print ('%s --> %s' % (row.object_name, row.created))\n 12 # close down\n 13 cur.close()\t\n 14 con.close()\n\nIn this example, cy_Oracle works just as cx_Oracle - the only difference\nis line 11. Here, cy_Oracle gives you an object with names of the selected\ncolumns as attributes whereas in cx_Oracle you will just get a collection.\n\nThe example needs a TNS-entry (here: bookdb) to locate the host of the \ndatabase server. As an alternative, it is possible to include the host,\nthe port an the service name into the connection::\n\n 3 myDB = OracleDB(databaseURL='user/password@dbhost:dbport/servicename')\n\n\nExample 2\n---------\n\nOracle object types are mostly used in complex database application\nthat are build from a mixture of SQL and PL/SQL. So, this \"simple\" \nexample using object types is one that is not very useful. It will\nlist all columns of all tables an views in the database schema \"book\"::\n\n 1 from cy_Oracle import OracleDB\n 2 from cy_Oracle import Attribute\n 3\n 4 # class to receive the result - one object of type T_COL_INFO.\n 5 class ColInfo(object):\n 6 def __init__(self):\n 7 self.name=None\n 8 self.oracleDataType=None\n 9 self.oracleDataLenght=None\n 10 \n 11 def __str__(self):\n 12 return 'name=%s type=%s(%d)' % \\\n 13 (self.name,self.oracleDataType,self.oracleDataLenght)\n 14\n 15 myDB = OracleDB(user='book', password='book', databaseURL='orcl')\n 16 con = myDB.connect()\n 17 cur = con.cursor()\n 18 # Create a new object type in the database\n 19 cur.execute(\"\"\" create or replace type T_COL_INFO as object(\n 20 NAME\t varchar2(85 char)\n 21 ,DATA_TYPE varchar2(106 char)\n 22 ,DATA_LENGTH number\n 23 ,COMMENTS varchar2(4000 char))\n 24 \"\"\")\n 25 # create a view containing objects of the type T_COL_INFO\n 26 cur.execute(\"\"\" create or replace view V_COL_INFO as\n 27 select \n 28 c.TABLE_NAME as TABLE_NAME \n 29 ,T_COL_INFO(c.COLUMN_NAME,c.DATA_TYPE,c.DATA_LENGTH,m.COMMENTS) \n 30 as COL_INFO\n 31 from USER_TAB_COLUMNS c ,USER_COL_COMMENTS m\n 32 where c.COLUMN_NAME = m.COLUMN_NAME and c.TABLE_NAME = m.TABLE_NAME\n 33 \"\"\")\n 34 # Create a type-mapping between T_COL_INFO and the Python object ColInfo\n 35 myDB.addTypemap(oracleTypename='T_COL_INFO',pythonClass=ColInfo,attrDict={\n 36 'name' \t\t\t: Attribute('NAME'),\n 37 'oracleDataType'\t : Attribute('DATA_TYPE'),\n 38 'oracleDataLenght'\t: Attribute('DATA_LENGTH'),\n 39 })\n 40 # select some objects from the database\n 41 for row in cur.execute(\"\"\" select TABLE_NAME,COL_INFO from V_COL_INFO order by 1 \"\"\"):\n 42 print 'Table::%s \"%s\"::%s' % \\\n 43 (row.table_name,row.col_info.__class__.__name__,row.col_info)\n 43 cur.close()\t\n 44 con.close()\n\nFirst of all, we need a Python class to receive the data from the \nOracle object type. In line 5, we create the class \"ColInfo\". To\nuse the class with cy_Oracle, it needs a constructor without \nparameters an \"object\" somewhere in its base classes.\n\nNow, we need an Oracle object type. We are using the DDL-statement in\nline 19 to create the type T_COL_INFO. It stores information about one colunm\nof a table or a view in the database.\n\nNext, we want to be able to receive objects of the type T_COL_INFO from the database.\nIn this example, we are creating the database view V_COL_INFO that contains this object \nin one of its columns - see line 26.\n\nThe interesting part of this example the code in line 35. In cx_Oracle, a SELECT\nfrom the view V_COL_INFO would return an object of the Python class cx_Oracle.Object.\nThis is a generic class, used for all Oracle object types with the following\nadvantages and disadvantages:\n\n* it is generic and contains all attributes of the Oracle object\n* all instances become inaccessable when closing the database connection \n* you can not derive your own Python class from cx_Oracle.Object\n\nWith the method \"addTypemap\" we tell cy_Oracle that:\n\n* we want an object of the Python class \"ColInfo\" each time a Oracle object\n of the object type \"T_COL_INFO\" shows up \n* we want an Oracle object of the object type \"T_COL_INFO\" each time a Python\n object of the class \"ColInfo\" shows up\n* we tell cy_Oracle how the attributes of the two types are mapped. \n\n\nThe output from the example depends on the objects in your database schema, but\nit should be something like this::\n\n Table::BOOK \"ColInfo\"::name=BK_ISBN type=NUMBER(22)\n Table::BOOK \"ColInfo\"::name=BK_BOOK type=T_BOOK(1)\n\nIt shows, that:\n\n* we got an object of the Python class \"ColInfo\" for each entry in view\n \"V_COL_INFO\".\n* We can add or override methods in \"ColInfo\" as usual \n\nExample 3\n---------\n\nOracle object types can be build as a composition using other object types.\nThe following example shows how cy_Oracle handles compositions and collections\nof objects.\n\nWe are extending the example 2 to get one Python object for each table in our\nschema containing:\n\n* the name of the table\n* the remaining free space in the table\n* a collection of \"ColInfo\" (see Example 2) objects describing each of the columns. \n\nThe exmple also shows that cy_Oracle is able to deal with composit Object\nobject types::\n\n 1 \"\"\" Example using Oracle Object Types\n 2 \n 3 This example shows how to map composit\n 4 Oracle object types as well collections\n 5 to Python objects using cy_Oracle.\n 6 \"\"\"\n 7 from cy_Oracle import OracleDB\n 8 from cy_Oracle import Attribute\n 9 from cy_Oracle import Collection\n 10 \n 11 # class to receive the result - one object of type T_COL_INFO.\n 12 class ColInfo(object):\n 13 \tdef __init__(self):\n 14 \t\tself.name=None\n 15 \t\tself.oracleDataType=None\n 16 \t\tself.oracleDataLenght=None\n 17 \tdef __str__(self):\n 18 \t\treturn 'name=%s type=%s(%d)' % \\\n 19 \t\t\t(self.name,self.oracleDataType,self.oracleDataLenght)\n 20 \n 21 # Class the receive the result - one object of type T_TAB_INFO\n 22 class TabInfo(object):\n 23 \tdef __init__(self):\n 24 \t\tself.name=None\n 25 \t\tself.pctFree=None\n 26 \t\tself.colInfo=None\n 27 \tdef __str__(self):\n 28 \t\tresult = 'name=%s free=%d(%%)' % (self.name,self.pctFree)\n 29 \t\tfor col in self.colInfo:\n 30 \t\t\tresult = '%s\\n %s' % (result,col)\n 31 \t\treturn result\n 32 \n 33 myDB = OracleDB(user='book', password='book', databaseURL='bookdb')\n 34 con = myDB.connect()\n 35 cur = con.cursor()\n 36 \n 37 # to be able to run this program more then once we must drop the existing types\n 38 try:\n 39 \tcur.execute(\"\"\" drop type T_TAB_INFO \"\"\")\n 40 except:\n 41 \tpass\n 42 try:\n 43 \tcur.execute(\"\"\" drop type T_COL_INFO_NT \"\"\")\n 44 except:\n 45 \tpass\n 46 \n 47 # Create a object type in the database\n 48 cur.execute(\"\"\" create or replace type T_COL_INFO as object(\n 49 \t\t NAME\t\tvarchar2(85 char)\n 50 \t\t,DATA_TYPE varchar2(106 char)\n 51 \t\t,DATA_LENGTH\tnumber\n 52 \t\t,COMMENTS varchar2(4000 char))\n 53 \t \"\"\")\n 54 # Create a collection type in the database\n 55 cur.execute(\"\"\" create or replace type T_COL_INFO_NT as table of T_COL_INFO \"\"\")\n 56 # Create the type that describes one table \n 57 cur.execute(\"\"\" create or replace type T_TAB_INFO as object(\n 58 \t\t NAME varchar2(30 char),\n 59 \t\t PCT_FREE number,\n 60 \t\t COL_INFO T_COL_INFO_NT)\n 61 \t \"\"\")\n 62 # create a view containing objects of the type T_COL_INFO\n 63 cur.execute(\"\"\" create or replace view V_TAB_INFO as \n 64 select T_TAB_INFO(\n 65 t.TABLE_NAME \n 66 ,t.PCT_FREE\n 67 ,cast(MULTISET( \n 68 \t SELECT T_COL_INFO(c.COLUMN_NAME,c.DATA_TYPE,c.DATA_LENGTH\n 69 \t\t\t,m.COMMENTS) from \n 70 \t USER_TAB_COLUMNS c,USER_COL_COMMENTS m\n 71 \t where c.TABLE_NAME=t.TABLE_NAME and c.TABLE_NAME=m.TABLE_NAME)\n 72 as T_COL_INFO_NT )\n 73 ) as TAB_INFO\n 74 from user_tables t\n 75 \"\"\")\n 76 \n 77 # Create a type-mapping between T_COL_INFO and the Python object ColInfo\n 78 myDB.addTypemap(oracleTypename='T_COL_INFO',pythonClass=ColInfo,attrDict={\n 79 \t'name' \t\t\t: Attribute('NAME'),\n 80 \t'oracleDataType'\t: Attribute('DATA_TYPE'),\n 81 \t'oracleDataLenght'\t: Attribute('DATA_LENGTH'),\n 82 \t})\n 83 # Create a type-mapping between T_TAB_INFO and the Python object ColInfo\n 84 myDB.addTypemap(oracleTypename='T_TAB_INFO',pythonClass=TabInfo,attrDict={\n 85 \t'name' \t\t\t: Attribute('NAME'),\n 86 \t'pctFree'\t\t: Attribute('PCT_FREE'),\n 87 \t'colInfo'\t\t: Collection('COL_INFO','T_COL_INFO_NT')\n 88 \t})\n 89 \n 90 # select some objects from the database\n 91 for row in cur.execute(\"\"\" select TAB_INFO from V_TAB_INFO \"\"\"):\n 92 \tprint '\\n%s' % (row.tab_info)\n 93 cur.close()\t\n 94 con.close()\n\n\nThe output from the example depends on the objects in your database schema, but\nit should be something like this::\n\n name=BOOK free=10(%)\n name=BK_BOOK type=T_BOOK(1)\n name=BK_ISBN type=NUMBER(22)\n name=BK_BOOK type=T_BOOK(1)\n name=BK_ISBN type=NUMBER(22)\n ...\n ...", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "cy-Oracle", "package_url": "https://pypi.org/project/cy-Oracle/", "platform": "", "project_url": "https://pypi.org/project/cy-Oracle/", "project_urls": null, "release_url": "https://pypi.org/project/cy-Oracle/0.4.0/", "requires_dist": null, "requires_python": "", "summary": "Extension to cx_Oracle to handle Oracle object types", "version": "0.4.0" }, "last_serial": 4648350, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "ea15f430f493fe7b3400a1e0c8848c2b", "sha256": "990177966003b4573b21cd528f92620eff73be62fc51d084ebc138ef3858f924" }, "downloads": -1, "filename": "cy_Oracle-0.1.tar.gz", "has_sig": false, "md5_digest": "ea15f430f493fe7b3400a1e0c8848c2b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10630, "upload_time": "2018-09-14T16:54:36", "url": "https://files.pythonhosted.org/packages/12/73/9bc2062888fac8c77d91e8388d3299a9fee286c2791cfa19038c14e32885/cy_Oracle-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "bb87e8992fa0a808fdd905498f2010ce", "sha256": "34fdbc2667b45ee1c4cdb105c6e660b356f481d9977ab482fcfcbc5b20302f5d" }, "downloads": -1, "filename": "cy_Oracle-0.2.tar.gz", "has_sig": false, "md5_digest": "bb87e8992fa0a808fdd905498f2010ce", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15194, "upload_time": "2018-09-21T19:42:08", "url": "https://files.pythonhosted.org/packages/53/10/eafa4ab98f12b2e89fae5f1baa4f5c89d89d0e3b9cf60f050a700997c744/cy_Oracle-0.2.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "64893675eb59150d6bf656790475431d", "sha256": "09aee5ffe45f89bf773de3a3d9048bda889ff70ead18ddcc453d37b245d51c1e" }, "downloads": -1, "filename": "cy_Oracle-0.3.1.tar.gz", "has_sig": false, "md5_digest": "64893675eb59150d6bf656790475431d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17580, "upload_time": "2018-09-25T20:54:00", "url": "https://files.pythonhosted.org/packages/84/0d/f5d4dacea99413f20d7d97a85e801acb044eff60cb6b2ddf820c32d23e8d/cy_Oracle-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "6f857f816d9c0f195765181d81c9de3b", "sha256": "95df9efbd2ca57ae33fc146c15c0ef080e0ccdfc35b6ba36a564b6023aa686d8" }, "downloads": -1, "filename": "cy_Oracle-0.4.0.tar.gz", "has_sig": false, "md5_digest": "6f857f816d9c0f195765181d81c9de3b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17940, "upload_time": "2018-12-31T15:52:31", "url": "https://files.pythonhosted.org/packages/cb/17/36b75a552492024dede8631fc0bbdb480a7a7948892a62cb90c2b8e5c557/cy_Oracle-0.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "6f857f816d9c0f195765181d81c9de3b", "sha256": "95df9efbd2ca57ae33fc146c15c0ef080e0ccdfc35b6ba36a564b6023aa686d8" }, "downloads": -1, "filename": "cy_Oracle-0.4.0.tar.gz", "has_sig": false, "md5_digest": "6f857f816d9c0f195765181d81c9de3b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17940, "upload_time": "2018-12-31T15:52:31", "url": "https://files.pythonhosted.org/packages/cb/17/36b75a552492024dede8631fc0bbdb480a7a7948892a62cb90c2b8e5c557/cy_Oracle-0.4.0.tar.gz" } ] }