Nearby lessons
107 of 112Python Database Programming - Storage Areas & Introduction
Introduction
Before learning Python Database Programming, first we should understand where data is stored in an application and why databases are required.
As part of an application, we may need to store different types of information.
For example:
- Customer Information
- Billing Information
- Calls Information
- Other Application Data
To store this information, we require Storage Areas.
Application
│
▼
Generates Data
│
▼
Needs Storage
│
▼
Storage Areas
Storage Areas
A Storage Area is a location where application data can be stored.
According to the document, Storage Areas are divided into two types:
- Temporary Storage Areas
- Permanent Storage Areas
Storage Areas
│
┌───────────┴───────────┐
│ │
▼ ▼
Temporary Storage Permanent Storage
Areas Areas
The major difference between them is how long the stored data remains available.
1. Temporary Storage Areas
Temporary Storage Areas are memory locations where data is stored only for a short period of time.
In Python, examples include:
- List
- Tuple
- Dictionary
These Python objects hold data while the program is running.
Python Program Starts
│
▼
Create Python Objects
│
├── List
├── Tuple
└── Dictionary
│
▼
Data Available
While Program Runs
Temporary Storage Examples
Consider some simple Python objects.
List
students = ["Durga", "Ravi", "Sunny"]
Tuple
employee = (100, "Durga", 1000)
Dictionary
customer = {
"id": 101,
"name": "Durga"
}
All these objects can hold information during program execution.
But they are considered temporary storage for this discussion because the data exists in program memory and is not automatically persisted after the program finishes.
What Happens After Program Execution?
Once the Python program completes its execution:
- The objects are destroyed automatically.
- The stored data is lost.
Program Running
│
▼
List / Tuple / Dictionary
│
▼
Data Available
│
▼
Program Completes
│
▼
Objects Destroyed
│
▼
Stored Data Lost
Therefore, Temporary Storage Areas are not suitable for storing data permanently.
Temporary Storage Area - Key Characteristics
| Characteristic | Description |
|---|---|
| Storage Duration | Short-term |
| Data Availability | Normally available while the program is running |
| Examples | List, Tuple, Dictionary |
| After Program Ends | Objects are destroyed and non-persisted data is lost |
| Permanent Storage | No |
2. Permanent Storage Areas
Permanent Storage Areas are also called Persistent Storage Areas.
These storage areas are used when application data must be stored permanently.
Examples given in the document are:
- File Systems
- Databases
- Data Warehouses
- Big Data Technologies
Permanent Storage Areas
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
File Systems Databases Data Warehouses
│
▼
Big Data Technologies
Unlike temporary storage, persistent storage is intended to keep data available even after the application stops.
Temporary vs Permanent Storage
| Temporary Storage | Permanent Storage |
|---|---|
| Stores data temporarily | Stores data persistently |
| Data is associated with program execution | Data remains available after program execution |
| Examples: List, Tuple, Dictionary | Examples: File System, Database, Data Warehouse, Big Data Technologies |
| Not suitable for permanent application records | Suitable for persistent application records |
File Systems
A File System is one type of Permanent Storage Area.
According to the document:
A File System is provided by the local operating system.
It is suitable for storing a small amount of information.
Application
│
▼
Operating System
│
▼
File System
│
▼
Files
│
▼
Persistent Data
Although File Systems provide permanent storage, they have several limitations for larger and more complex data-management requirements.
Limitations of File Systems
The document explains four major limitations of File Systems:
- Cannot Store Huge Amount of Information
- No Query Language Support
- No Security
- Duplicate Data Problem
File System
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
Limited for No Query No Database-
Huge Data Language Level Security
│
▼
Duplicate Data
│
▼
Data Inconsistency
Limitation 1 - Cannot Store Huge Amount of Information
According to the document, a File System is not suitable for storing a very large amount of data.
For small applications, files may be sufficient.
But when the amount of application information becomes very large, managing everything using ordinary files becomes difficult.
Small Amount of Data
│
▼
File System
│
▼
Suitable
Very Large Amount of Data
│
▼
File System
│
▼
Not Suitable
Limitation 2 - No Query Language Support
According to the document, File Systems do not provide query-language support like a database.
Because of this, performing complex operations on stored data becomes difficult.
For example, in a database we can use SQL statements such as:
SELECT * FROM employees;
or:
SELECT * FROM employees WHERE esal > 5000;
A normal File System does not provide SQL-style query processing automatically.
Database │ ▼ Query Language │ ▼ Easy Data Operations File System │ ▼ No Built-in SQL Query Language │ ▼ Operations Become More Complex
Limitation 3 - No Security
The document identifies lack of database-style security as another limitation of File Systems.
A database normally provides controlled access through authentication and authorization mechanisms.
For example:
- Username
- Password
File-based storage by itself does not provide the same database-level access-control mechanism.
File System
│
▼
No Built-in Database
Security Mechanism
Limitation 4 - Duplicate Data Problem
Another problem discussed in the document is duplicate data.
In simple File Systems, there may be no database constraint mechanism to prevent the same logical record from being stored multiple times.
For example:
100, Durga, 1000, Hyd 100, Durga, 1000, Hyd 100, Durga, 1000, Hyd
Repeated information can create a Data Inconsistency Problem.
Duplicate Data
│
▼
Same Information
Stored Multiple Times
│
▼
Different Copies May
Become Different
│
▼
Data Inconsistency
Why Do We Need Databases?
To overcome the limitations of File Systems, we can use Databases.
Databases provide better facilities for storing, organizing, searching, securing, and managing application data.
File System Problems
│
├── Limited for huge data
├── No query-language support
├── Limited database-level security
└── Duplicate-data problems
│
▼
Need Better Data Management
│
▼
Database
Databases
A Database is a Permanent Storage Area used to store and manage application data in an organized manner.
The document explains several advantages of using Databases over File Systems.
Advantages of Databases
- Can Store Huge Amount of Information
- Query Language Support
- Data Security
- No Data Duplication
Advantage 1 - Can Store Huge Amount of Information
According to the document, a Database can store a very large amount of information compared with ordinary File System storage used for application data.
Large Application Data
│
▼
Database
│
▼
Large Amount of
Structured Information
This makes databases suitable for applications that manage many records.
Advantage 2 - Query Language Support
Every Database provides some form of Query Language support.
For relational databases, SQL is commonly used.
SQL stands for:
Structured Query Language
Using SQL, we can perform operations such as:
- Create
- Insert
- Select
- Update
- Delete
For example:
SELECT * FROM employees;
Because query-language support is available, database operations become easier.
Advantage 3 - Data Security
Databases provide security mechanisms for controlling access to stored information.
The document explains that to access data present inside a Database, valid credentials such as:
- Username
- Password
are required.
User
│
▼
Username + Password
│
▼
Database Authentication
│
├── Valid
│ │
│ ▼
│ Access
│
└── Invalid
│
▼
Denied
Therefore, databases provide mechanisms for securing stored information.
Advantage 4 - No Data Duplication
Inside a relational Database, data is commonly organized in the form of Tables.
While designing database tables, Database Administrators can use techniques and constraints such as:
- Normalization Techniques
- Unique Key Constraints
- Primary Key Constraints
These mechanisms help control duplicate data.
Database Table Design
│
├── Normalization
├── Unique Key
└── Primary Key
│
▼
Reduce / Prevent
Unwanted Duplication
│
▼
Better Data Consistency
Primary Key Example
For example, consider an employee table:
| eno | ename | esal | eaddr |
|---|---|---|---|
| 100 | Durga | 1000 | Hyd |
| 200 | Ravi | 2000 | Mumbai |
If eno is declared as a Primary Key, duplicate employee numbers are not allowed.
eno = 100
│
▼
Already Exists
│
▼
Duplicate Primary-Key Value
Not Allowed
File System vs Database
| File System | Database |
|---|---|
| Suitable for comparatively small/simple storage requirements | Suitable for managing large structured datasets |
| No built-in SQL-style query language | Provides query-language support |
| No database-level security by itself | Provides authentication/security mechanisms |
| Duplicate-data control is difficult | Constraints and normalization help control duplication |
| Complex data operations may require custom programming | Queries make many data operations easier |
Limitations of Databases
Although Databases solve many File System problems, the document also discusses limitations of traditional databases.
The two limitations highlighted are:
- Cannot Hold Extremely Huge Data
- Supports Mainly Structured Data
Limitation 1 - Cannot Hold Extremely Huge Data
The document states that a traditional Database is not intended for extremely huge amounts of information such as very large Terabyte-scale datasets.
Normal Structured Data
│
▼
Traditional Database
│
▼
Suitable
Extremely Huge Data
│
▼
Traditional Database
│
▼
May Require More
Advanced Technologies
This is where technologies designed for large-scale distributed data processing can become useful.
Limitation 2 - Supports Structured Data
The document mainly describes traditional relational Databases as supporting:
- Structured Data
- Tabular Data
- Relational Data
Examples include data arranged in rows and columns.
| eno | ename | esal |
|---|---|---|
| 100 | Durga | 1000 |
| 200 | Ravi | 2000 |
This is an example of structured/tabular data.
Structured, Semi-Structured and Unstructured Data
The document distinguishes structured data from other forms of data.
| Data Type | Examples |
|---|---|
| Structured Data | Tables, rows, columns, relational records |
| Semi-Structured Data | XML Files |
| Unstructured Data | Video Files, Audio Files, Images |
Data
│
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
Structured Semi-Structured Unstructured
│ │ │
▼ ▼ ▼
Tables XML Video / Audio
/ Images
How to Overcome Database Limitations?
To overcome the limitations discussed for traditional Databases, the document introduces more advanced storage technologies.
- Big Data Technologies
- Data Warehouses
Traditional Database
│
▼
Limitations
│
├── Extremely huge data requirements
└── Different data forms / analytical requirements
│
▼
Advanced Storage Technologies
│
├── Big Data Technologies
└── Data Warehouses
Storage Technology Overview
| Storage Area | Main Purpose in This Tutorial |
|---|---|
| List / Tuple / Dictionary | Temporary in-program storage |
| File System | Permanent storage for comparatively small/simple data requirements |
| Database | Persistent management of large structured data |
| Data Warehouse | Advanced persistent storage, especially for analytical data |
| Big Data Technologies | Technologies for very large and varied datasets |
What is Python Database Programming?
Sometimes, as part of programming requirements, we need to connect a Python program with a Database.
After establishing the connection, the Python application can perform different database operations.
Examples include:
- Creating Tables
- Inserting Data
- Updating Data
- Deleting Data
- Selecting Data
The process of communicating with a Database from a Python program is called Python Database Programming.
Python Program
│
▼
Database Connection
│
▼
Database
│
├── Create
├── Insert
├── Update
├── Delete
└── Select
Database Operations
| Operation | Purpose |
|---|---|
| Create | Create database objects such as tables |
| Insert | Add new records |
| Update | Modify existing records |
| Delete | Remove records |
| Select | Retrieve records |
These operations form the foundation of database programming.
SQL and Python
We use SQL to communicate with relational Databases.
SQL stands for:
Structured Query Language
Python is used to send these SQL commands to the Database through an appropriate database driver/module.
So, in simple terms:
- SQL describes the Database operation.
- Python sends or executes those SQL commands through the database interface.
Python Program
│
▼
SQL Command
│
▼
Database Driver
│
▼
Database
│
▼
Operation Performed
SQL Operations Example
For example, suppose Python sends the following SQL command:
SELECT * FROM employees;
The Database executes the query and returns the employee records.
Python │ ▼ "SELECT * FROM employees" │ ▼ Database │ ▼ Execute SELECT │ ▼ Employee Records │ ▼ Python Program
Python and SQL Responsibilities
| Technology | Responsibility |
|---|---|
| Python | Application logic and sending/executing SQL through a database module |
| SQL | Describes operations to perform on relational database data |
| Database | Stores and manages persistent data and executes supported queries |
Python │ │ Sends SQL ▼ Database │ │ Executes Operation ▼ Result │ ▼ Python
Databases Supported by Python
The document lists several databases that can be accessed from Python.
- Oracle
- MySQL
- SQL Server
- GadFly
- SQLite
Python
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
Oracle MySQL SQL Server
│ │
└──────────┐ ┌────────┘
▼ ▼
GadFly SQLite
Different databases can require different Python drivers or modules for communication.
Database-Specific Modules
Python database communication requires an appropriate database-specific module or driver.
Examples provided in the document include:
| Database | Module |
|---|---|
| Oracle Database | cx_Oracle |
| Microsoft SQL Server | pymssql |
For example:
Python Program
│
▼
cx_Oracle
│
▼
Oracle Database
Similarly:
Python Program
│
▼
pymssql
│
▼
Microsoft SQL Server
Why is a Database Module Required?
Python and a database system require a software interface for communication.
A database-specific module or driver provides this interface.
Python Program
│
▼
Database Module / Driver
│
▼
Database
Later parts of this tutorial explain this concept in detail while working with Oracle and MySQL.
Complete Concept Flow
Application Data
│
▼
Storage Areas
│
┌────────────┴────────────┐
│ │
▼ ▼
Temporary Storage Permanent Storage
│ │
┌─────────┼─────────┐ ┌──────┼──────────────┐
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
List Tuple Dictionary Files Database Data Warehouse
│
▼
Structured Data
│
▼
Python Database Programming
│
▼
Python Program
│
▼
SQL
│
▼
Database Module/Driver
│
▼
Database
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
Insert Update Delete
│ │
└──────────┐ ┌──────────┘
▼ ▼
Select / Create
Execution Flow of Python Database Programming
Program Starts
│
▼
Python Application
│
▼
Connect to Database
│
▼
Send SQL Command
│
▼
Database Executes Command
│
▼
Database Operation
│
├── Create Table
├── Insert Data
├── Update Data
├── Delete Data
└── Select Data
│
▼
Return Result if Required
│
▼
Python Program
│
▼
Program Ends
The exact connection and execution steps will be covered in the next part.
Storage Areas Comparison
| Storage Area | Permanent? | Typical Data | Main Point |
|---|---|---|---|
| List | No | Python objects | Temporary program data |
| Tuple | No | Python objects | Temporary program data |
| Dictionary | No | Key-value program data | Temporary program data |
| File System | Yes | Files | Persistent storage |
| Database | Yes | Structured/tabular data | Query-based data management |
| Data Warehouse | Yes | Large analytical datasets | Advanced storage and analytics |
| Big Data Technologies | Yes | Very large/varied datasets | Large-scale data processing and storage |
File System Limitations vs Database Advantages
| File System Limitation | Database Advantage |
|---|---|
| Not suitable for very large application data | Can manage large amounts of structured information |
| No built-in SQL-style query support | Provides query-language support |
| No database-level security mechanism by itself | Provides authentication and access controls |
| Duplicate-data control is difficult | Keys, constraints and normalization help control duplication |
Important Terminology
| Term | Meaning |
|---|---|
| Storage Area | A location used for storing application data |
| Temporary Storage | Storage used while a program is executing |
| Persistent Storage | Storage intended to retain data permanently |
| File System | Operating-system-based file storage |
| Database | System for organized persistent data storage and management |
| Structured Data | Data organized according to a defined structure such as rows and columns |
| Semi-Structured Data | Data with some structure, such as XML |
| Unstructured Data | Data such as video, audio and images |
| SQL | Structured Query Language |
| Python Database Programming | Using Python to communicate with databases and perform database operations |
Quick Revision
Storage Areas
│
├── Temporary
│ │
│ ├── List
│ ├── Tuple
│ └── Dictionary
│
└── Permanent
│
├── File System
├── Database
├── Data Warehouse
└── Big Data Technologies
File System
│
├── Suitable for small/simple storage
├── No built-in SQL query language
├── Limited database-level security
└── Duplicate-data problems
Database
│
├── Large structured data
├── Query-language support
├── Security
└── Duplicate-data control
Python Database Programming
│
▼
Python
│
▼
SQL
│
▼
Database
│
├── Create
├── Insert
├── Update
├── Delete
└── Select
Summary
- Applications require Storage Areas to store information such as customer, billing and call information.
- Storage Areas are broadly divided into Temporary Storage Areas and Permanent Storage Areas.
- List, Tuple and Dictionary are examples of temporary in-program storage.
- Temporary data that is not persisted is lost after the program terminates.
- Permanent Storage Areas are also called Persistent Storage Areas.
- File Systems, Databases, Data Warehouses and Big Data Technologies are examples of Permanent Storage Areas.
- A File System is provided by the local operating system and is suitable for comparatively small/simple storage requirements.
- The document identifies limitations of File Systems such as difficulty handling huge data, lack of query-language support, lack of database-style security, and duplicate-data problems.
- Databases overcome many File System limitations.
- Databases provide query-language support and security mechanisms.
- Normalization, Unique Keys and Primary Keys can help prevent unwanted duplicate data.
- Traditional relational databases primarily work with structured, tabular and relational data.
- The document gives XML as an example of Semi-Structured Data.
- Video, Audio and Images are examples of Unstructured Data.
- Big Data Technologies and Data Warehouses are introduced for more advanced storage requirements.
- Python Database Programming means connecting a Python program with a Database and performing database operations.
- Common operations include Creating Tables, Inserting, Updating, Deleting and Selecting data.
- SQL stands for Structured Query Language.
- Python sends/executes SQL commands through an appropriate database interface.
- The document lists Oracle, MySQL, SQL Server, GadFly and SQLite among databases accessible from Python.
- Examples of database-specific modules include
cx_Oraclefor Oracle andpymssqlfor Microsoft SQL Server.
Important Notes
- Do not confuse temporary Python objects with persistent storage. A List, Tuple or Dictionary does not automatically survive after program termination.
- Permanent Storage Areas are also known as Persistent Storage Areas.
- A File System is useful for persistent file storage, but database systems provide specialized facilities for structured data management.
- Query-language support is one of the major advantages of relational databases.
- Database constraints such as Primary Keys and Unique Keys help control duplicate values.
- Normalization is a database-design technique used to organize data and reduce undesirable redundancy.
- Authentication through a username and password is one part of database security; real database systems can provide additional authorization mechanisms.
- The document's database limitations describe traditional relational-database use cases. Modern database systems can also handle very large datasets and various non-tabular data types, depending on the technology.
- Python itself does not replace SQL. Python application code uses database drivers/modules to send SQL operations to relational databases.
- Different database systems can require different Python drivers.
- This part provides the foundation required before learning the standard Python Database Programming steps.
Part 1 - Final Concept
Application
│
▼
Needs to Store Data
│
▼
Storage Areas
│
├──────── Temporary
│ │
│ ├── List
│ ├── Tuple
│ └── Dictionary
│
└──────── Permanent
│
├── File System
├── Database
├── Data Warehouse
└── Big Data Technologies
│
▼
Database Selected
│
▼
Python Program
│
▼
SQL
│
▼
Database
│
┌──────────┼──────────┐
│ │ │
▼ ▼ ▼
Insert Update Delete
│ │
└─────────┬───────────┘
▼
Select
Part 1 Completed
Next: Part 2 — Standard Steps for Python Database Programming
Introduction
Whenever we want to communicate with a Database from a Python program, we should follow a standard sequence of steps.
These steps form the basic procedure of Python Database Programming.
According to the document, there are 7 standard steps.
Python Program
│
▼
Import Database Module
│
▼
Establish Connection
│
▼
Create Cursor
│
▼
Execute SQL Queries
│
▼
Commit / Rollback
│
▼
Fetch Results
│
▼
Close Resources
Standard Steps for Python Database Programming
The seven standard steps are:
- Import the database-specific module
- Establish the connection
- Create a Cursor object
- Execute SQL queries
- Commit or Rollback changes
- Fetch the results
- Close the resources
| Step | Operation | Main Method / Statement |
|---|---|---|
| 1 | Import database-specific module | import cx_Oracle |
| 2 | Establish connection | connect() |
| 3 | Create Cursor object | cursor() |
| 4 | Execute SQL queries | execute(), executescript(), executemany() |
| 5 | Save or cancel changes | commit(), rollback() |
| 6 | Fetch SELECT results | fetchone(), fetchall(), fetchmany(n) |
| 7 | Close resources | close() |
Step 1 — Import Database Specific Module
The first step is to import the module required for the Database we want to use.
For example, the document uses the following module for Oracle Database:
import cx_Oracle
The database-specific module acts as a bridge between the Python program and the Database.
Python Program
│
▼
Database-Specific Module
│
▼
Database
For Oracle in the document:
Python │ ▼ cx_Oracle │ ▼ Oracle Database
Why Do We Import a Database Module?
Python needs an appropriate module or driver to communicate with a particular Database.
The module provides the functions and classes required to:
- Connect to the Database
- Create Cursor objects
- Execute SQL statements
- Fetch results
- Manage transactions
- Close database resources
For the Oracle examples in this chapter:
import cx_Oracle
is used.
Step 2 — Establish Connection
After importing the database-specific module, the next step is to establish a connection between the Python program and the Database.
A Connection object can be created by using the:
connect()
function.
Syntax
con = cx_Oracle.connect(database_information)
Example
con = cx_Oracle.connect('scott/tiger@localhost')
Here:
conis the Connection object.connect()establishes the connection with the Oracle Database.
Understanding the Connection Example
Consider:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection information used in the example is:
| Part | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database / Host information | localhost |
scott / tiger @ localhost │ │ │ │ │ └── Database connection information │ │ │ └── Password │ └── Username
The Connection object returned by connect() is stored in:
con
Connection Object
The object returned by:
cx_Oracle.connect(...)
is called a Connection object.
In the document, it is stored in:
con
The Connection object is important because it is used for operations such as:
- Creating a Cursor object
- Committing transactions
- Rolling back transactions
- Closing the Database connection
con
│
┌───────┼───────┐
│ │ │
▼ ▼ ▼
cursor() commit() rollback()
│
└──────────┐
▼
close()
Step 3 — Create Cursor Object
To execute SQL queries and hold their results, we require a special object called a Cursor object.
A Cursor object can be created by using the:
cursor()
method of the Connection object.
Syntax
cursor = con.cursor()
Here:
conrepresents the Connection object.cursor()creates a Cursor object.cursorstores the returned Cursor object.
What is a Cursor Object?
A Cursor object is used to execute SQL statements and work with query results.
Connection Object
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
Execute SQL
For example:
cursor = con.cursor()
After creating the Cursor object, we can use it to execute SQL queries.
cursor.execute(...)
Connection Object vs Cursor Object
| Connection Object | Cursor Object |
|---|---|
| Represents the connection with the Database | Used for executing SQL statements |
Created using connect() |
Created using cursor() |
Example variable: con |
Example variable: cursor |
Used for commit() and rollback() |
Used for execute() and fetching results |
Closed using con.close() |
Closed using cursor.close() |
Step 4 — Execute SQL Queries
After creating the Cursor object, we can execute SQL queries.
SQL queries are executed by using methods of the Cursor object.
The document lists the following three important methods:
execute()executescript()executemany()
Cursor Object
│
├── execute()
│
├── executescript()
│
└── executemany()
1. execute()
The execute() method is used to execute a single SQL query.
Syntax
cursor.execute(sqlquery)
Example
cursor.execute("select * from employees")
This statement executes:
select * from employees
against the connected Database.
Cursor │ ▼ execute() │ ▼ Single SQL Query │ ▼ Database
execute() Example Explanation
Consider:
cursor.execute("select * from employees")
Here:
cursoris the Cursor object.execute()executes one SQL statement.select * from employeesretrieves employee records.
The result of a SELECT query can then be obtained using fetch methods such as:
fetchone() fetchall() fetchmany(n)
2. executescript()
The document describes executescript() as a method used to execute a string containing multiple SQL queries separated by a semicolon:
;
Syntax
cursor.executescript(sqlqueries)
Conceptually:
SQL Query 1; SQL Query 2; SQL Query 3;
can be provided as a SQL script when the particular database interface supports this method.
Cursor │ ▼ executescript() │ ▼ Multiple SQL Statements Separated by ;
3. executemany()
The executemany() method is used to execute a parameterized query for multiple sets of values.
Syntax shown in the document
cursor.executemany()
Later in this chapter, we will use this method for inserting multiple employee records.
Conceptually:
One Parameterized SQL Query
│
▼
Multiple Records
│
▼
executemany()
│
▼
Database
execute() vs executescript() vs executemany()
| Method | Purpose |
|---|---|
execute() |
Executes a single SQL query |
executescript() |
Executes a script/string containing multiple SQL queries separated by semicolons, when supported |
executemany() |
Executes a parameterized SQL operation for multiple sets of values |
Step 5 — Commit or Rollback Changes
The next step is transaction management.
This step is especially required for DML — Data Manipulation Language operations such as:
- INSERT
- UPDATE
- DELETE
DML Operations
│
├── INSERT
├── UPDATE
└── DELETE
│
▼
Commit or Rollback
Two important methods are:
commit() rollback()
commit()
The commit() method saves the changes permanently to the Database.
Syntax
con.commit()
Purpose:
- Saves the changes made during the transaction.
- Makes the transaction changes permanent.
INSERT / UPDATE / DELETE
│
▼
Temporary Changes
│
▼
con.commit()
│
▼
Changes Saved
rollback()
The rollback() method rolls back the temporary changes in the current transaction.
Syntax
con.rollback()
Purpose:
- Cancels transaction changes that have not been committed.
- Returns the transaction to the appropriate previous state according to the database transaction rules.
INSERT / UPDATE / DELETE
│
▼
Temporary Changes
│
▼
Error / Problem
│
▼
con.rollback()
│
▼
Uncommitted Changes
Rolled Back
commit() vs rollback()
| commit() | rollback() |
|---|---|
| Saves transaction changes | Cancels uncommitted transaction changes |
| Makes changes permanent | Rolls changes back |
| Used after successful DML operations | Commonly used when a transaction must be cancelled, such as after an error |
con.commit() |
con.rollback() |
DML Transaction Flow
DML Query
│
▼
INSERT / UPDATE / DELETE
│
▼
Execute Query
│
▼
Was it successful?
/ \
Yes No
│ │
▼ ▼
commit() rollback()
│ │
▼ ▼
Save Changes Cancel
Uncommitted
Changes
Step 6 — Fetch Results
Fetching results is required for SELECT queries.
After executing a SELECT statement, the Cursor object can be used to retrieve the returned rows.
The document lists three important fetch methods:
fetchone()fetchall()fetchmany(n)
SELECT Query
│
▼
Cursor Result
│
├── fetchone()
├── fetchall()
└── fetchmany(n)
1. fetchone()
The fetchone() method fetches only one row from the result set.
Example
data = cursor.fetchone() print(data)
Here:
cursor.fetchone()fetches one row.- The fetched row is stored in
data. print(data)displays the row.
SELECT Result
│
▼
fetchone()
│
▼
One Row
│
▼
data
fetchone() Example
main.py
No output captured.
2. fetchall()
The fetchall() method fetches all remaining rows from the query result.
The document states that it returns a list of rows.
Example
data = cursor.fetchall()
for row in data:
print(row)
The fetched rows are stored in:
data
A for loop is then used to process every row.
fetchall() Example
main.py
No output captured.
fetchall() Execution
SELECT Query
│
▼
Multiple Rows Returned
│
▼
cursor.fetchall()
│
▼
Collection of Rows
│
▼
data
│
▼
for row in data
│
▼
Print Each Row
3. fetchmany(n)
The fetchmany(n) method fetches up to the specified number of rows from the result set.
Syntax
cursor.fetchmany(n)
For example:
cursor.fetchmany(3)
requests up to three rows from the current result-set position.
Result Set
│
▼
fetchmany(3)
│
▼
Up to 3 Rows
fetchone() vs fetchall() vs fetchmany(n)
| Method | Purpose |
|---|---|
fetchone() |
Fetches one row |
fetchall() |
Fetches all remaining rows |
fetchmany(n) |
Fetches up to n rows |
SELECT Result
│
├── Need one row?
│ └── fetchone()
│
├── Need all rows?
│ └── fetchall()
│
└── Need a limited batch?
└── fetchmany(n)
DML Queries vs SELECT Queries
| DML Queries | SELECT Queries |
|---|---|
| INSERT | Retrieve data |
| UPDATE | Use fetch methods to obtain rows |
| DELETE | fetchone() |
| Normally require transaction handling | fetchall() |
commit() / rollback() |
fetchmany(n) |
Step 7 — Close Resources
After completing all Database operations, it is highly recommended to close the resources.
The document says that resources should be closed in the reverse order of their opening.
We created:
1. Connection 2. Cursor
Therefore, while closing:
1. Cursor 2. Connection
Close Cursor
cursor.close()
Close Connection
con.close()
Why Reverse Order?
The Cursor depends on the Connection.
Connection
│
▼
Cursor
Therefore, cleanup is performed in reverse:
Cursor
│
▼
Close Cursor
│
▼
Close Connection
The code is:
cursor.close() con.close()
Resource Opening and Closing Order
| Opening Order | Closing Order |
|---|---|
| 1. Connection | 1. Cursor |
| 2. Cursor | 2. Connection |
OPEN
Connection
│
▼
Cursor
CLOSE
Cursor
│
▼
Connection
Important Methods for Python Database Programming
According to the document, the following methods are important for Python Database Programming:
connect() cursor() execute() executescript() executemany() commit() rollback() fetchone() fetchall() fetchmany(n) fetch close()
| Method | Purpose |
|---|---|
connect() |
Establishes a Database connection |
cursor() |
Creates a Cursor object |
execute() |
Executes a single SQL query |
executescript() |
Executes multiple SQL statements as a script when supported |
executemany() |
Executes a parameterized operation for multiple sets of values |
commit() |
Saves transaction changes |
rollback() |
Rolls back uncommitted transaction changes |
fetchone() |
Fetches one row |
fetchall() |
Fetches all remaining rows |
fetchmany(n) |
Fetches up to n rows |
fetch |
Listed in the source document among important database-programming methods |
close() |
Closes database resources |
Important Note from the Document
The document states that these important database-programming methods remain generally common while working with different databases.
connect() cursor() execute() executescript() executemany() commit() rollback() fetchone() fetchall() fetchmany(n) close()
However, the database-specific module, connection details, parameter styles, and exact API support can differ between database drivers.
For example:
Oracle │ ▼ cx_Oracle MySQL │ ▼ MySQL-specific Connector
The overall database-programming workflow remains similar.
Complete Flow of Python Database Programming
Program Starts
│
▼
Import Database Module
│
▼
Establish Connection
│
▼
Create Cursor
│
▼
Execute SQL Queries
│
┌─────────┴─────────┐
│ │
▼ ▼
DML Query SELECT Query
│ │
INSERT / UPDATE / DELETE │
│ │
▼ ▼
Commit / Rollback Fetch Results
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
fetchone() fetchall() fetchmany(n)
│ │ │
└───────────┼───────────┘
│
▼
Close Cursor
│
▼
Close Connection
│
▼
Program Ends
Seven Steps - Detailed Execution Flow
Step 1
Import Database-Specific Module
│
▼
import cx_Oracle
│
▼
Step 2
Establish Connection
│
▼
con = cx_Oracle.connect(...)
│
▼
Step 3
Create Cursor Object
│
▼
cursor = con.cursor()
│
▼
Step 4
Execute SQL Query
│
▼
cursor.execute(...)
│
▼
Step 5
Commit / Rollback
│
▼
con.commit()
OR
con.rollback()
│
▼
Step 6
Fetch SELECT Results
│
┌───────┼───────┐
│ │ │
▼ ▼ ▼
fetchone fetchall fetchmany
│
▼
Step 7
Close Resources
│
▼
cursor.close()
│
▼
con.close()
Complete Conceptual Example
main.py
No output captured.
Conceptual Example Explanation
The previous program combines the main steps required for a simple SELECT operation.
1. Import Module
import cx_Oracle
2. Establish Connection
con = cx_Oracle.connect('scott/tiger@localhost')
3. Create Cursor
cursor = con.cursor()
4. Execute SELECT
cursor.execute("select * from employees")
5. Fetch All Rows
data = cursor.fetchall()
6. Display Rows
for row in data:
print(row)
7. Close Resources
cursor.close() con.close()
No commit() is shown here because this conceptual example only performs a SELECT operation.
Complete DML Conceptual Example
main.py
No output captured.
DML Example Execution Flow
Import cx_Oracle
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Execute INSERT
│
▼
con.commit()
│
▼
Changes Saved
│
▼
Close Cursor
│
▼
Close Connection
This demonstrates the difference between a SELECT operation and a DML operation.
For INSERT, UPDATE and DELETE operations, transaction management using commit() or rollback() becomes important.
Standard Steps Summary Table
| Step | Description |
|---|---|
| Step 1 | Import the database-specific module |
| Step 2 | Establish a connection using connect() |
| Step 3 | Create a Cursor object using cursor() |
| Step 4 | Execute SQL queries using execute(), executescript(), or executemany() |
| Step 5 | Save or cancel transaction changes using commit() or rollback() |
| Step 6 | Fetch SELECT-query results using fetchone(), fetchall(), or fetchmany(n) |
| Step 7 | Close the Cursor and Connection using close() |
Quick Revision
1. IMPORT
│
└── import cx_Oracle
│
▼
2. CONNECT
│
└── con = cx_Oracle.connect(...)
│
▼
3. CURSOR
│
└── cursor = con.cursor()
│
▼
4. EXECUTE
│
├── execute()
├── executescript()
└── executemany()
│
▼
5. TRANSACTION
│
├── commit()
└── rollback()
│
▼
6. FETCH
│
├── fetchone()
├── fetchall()
└── fetchmany(n)
│
▼
7. CLOSE
│
├── cursor.close()
└── con.close()
Summary
- Python Database Programming follows a standard sequence of steps.
- The document identifies seven standard steps.
- The first step is importing the database-specific module.
- For the Oracle examples, the document uses
cx_Oracle. connect()establishes a connection between Python and the Database.- The returned object is called a Connection object.
cursor()creates a Cursor object.- The Cursor object is used to execute SQL statements and work with query results.
execute()executes a single SQL query.- The document describes
executescript()for executing a string containing multiple SQL queries separated by semicolons. executemany()is used with a parameterized operation and multiple sets of values.- INSERT, UPDATE and DELETE are DML operations.
commit()saves transaction changes permanently.rollback()rolls back uncommitted transaction changes.- Fetch methods are used for SELECT-query results.
fetchone()fetches one row.fetchall()fetches all remaining rows.fetchmany(n)fetches up to the requested number of rows.- Database resources should be closed after completing operations.
- The Cursor should be closed before the Connection when following the reverse order of resource creation.
cursor.close()closes the Cursor.con.close()closes the Connection.
Important Notes
- The seven steps form the basic workflow for Python Database Programming.
- The database-specific module can change depending on the Database.
- The document uses
cx_Oraclefor its Oracle examples. - A Connection object represents the active database connection.
- A Cursor object is required for executing SQL statements.
execute()is used for a single SQL statement.executemany()is useful when the same parameterized operation must be performed for multiple records.commit()androllback()are transaction-management methods.- Use fetch methods when processing rows returned by SELECT queries.
fetchone(),fetchall()andfetchmany(n)serve different result-fetching requirements.- Always release Database resources after use.
- Resources should be closed in reverse order: Cursor first, then Connection.
- The source document lists
fetchamong important methods, but standard Python DB-API cursor interfaces normally expose specific methods such asfetchone(),fetchmany(), andfetchall(). - Although the overall workflow is common, exact methods supported by a driver can differ. For example,
executescript()is not a universal method of every Python database driver. - Connection syntax and SQL parameter styles can also vary between database drivers.
Part 2 - Final Concept
Python Database Programming
│
▼
1. Import Module
│
▼
2. Connect Database
│
▼
3. Create Cursor
│
▼
4. Execute SQL
│
┌─────────┴─────────┐
│ │
▼ ▼
DML SELECT
│ │
▼ ▼
5. Commit / Rollback 6. Fetch Data
│ │
└─────────┬─────────┘
▼
7. Close Cursor
│
▼
Close Connection
│
▼
END
Part 2 Completed
Next: Part 3 — Working with Oracle Database: Driver, cx_Oracle, Installation & Testing
Introduction
Before a Python program can communicate with an Oracle Database, we require a special software component called a Driver or Connector.
This part explains:
- Working with Oracle Database
- Why a Driver is required
- Driver / Connector
cx_Oracle- Features of
cx_Oracle - Installing
cx_Oracle - Installation output
- Testing the installation
help("modules")- Important Points
Python Program
│
▼
Driver / Connector
│
▼
Oracle Database
Working with Oracle Database
From a Python program, if we want to communicate with any Database, some translator is required.
The translator is responsible for converting:
- Python calls into Database-specific calls
- Database-specific calls into Python calls
This translator is called a:
Driver / Connector
Therefore, a Driver acts as the communication layer between the Python application and the Database.
Why is a Driver Required?
A Python program and an Oracle Database use different interfaces for communication.
Therefore, an intermediate component is required to translate the communication between them.
This component is the Database Driver.
Python Program
│
│ Python Calls
▼
Driver / Connector
│
│ Oracle-Specific Calls
▼
Oracle Database
When Oracle sends information back:
Oracle Database
│
│ Oracle Response
▼
Driver / Connector
│
│ Python-Compatible Response
▼
Python Program
Driver / Connector
A Driver or Connector is a translator between a Python program and a Database.
Its main responsibilities are:
- Receive calls from the Python program.
- Convert Python calls into Database-specific calls.
- Send those calls to the Database.
- Receive responses from the Database.
- Convert Database-specific responses into a form usable by Python.
Driver / Connector
│
┌───────────┴───────────┐
│ │
▼ ▼
Python → Database Database → Python
Translation Translation
Driver / Connector Diagram
The communication architecture can be represented as:
+-----------------------+
| Python Program |
+-----------------------+
│
│ Python Calls
▼
+-----------------------+
| Driver / Connector |
| cx_Oracle |
+-----------------------+
│
│ Oracle-Specific Calls
▼
+-----------------------+
| Oracle Database |
+-----------------------+
The Driver works as a bridge between Python and Oracle Database.
Two-Way Communication
The communication is not only from Python to Oracle. It works in both directions.
Python Program
│
│ Request
▼
cx_Oracle
│
│ Oracle Request
▼
Oracle Database
│
│ Result / Response
▼
cx_Oracle
│
│ Python-Compatible Result
▼
Python Program
Therefore, the Driver handles both requests and responses.
Oracle Database Driver
According to the document, the Driver required for Oracle Database is:
cx_Oracle
cx_Oracle is a Python extension module that enables access to Oracle Database.
Python │ ▼ cx_Oracle │ ▼ Oracle Database
In the examples that follow in this chapter, cx_Oracle is used for Python-to-Oracle communication.
What is cx_Oracle?
cx_Oracle is a Python extension module that enables Python programs to access Oracle Database.
It provides the functionality required to:
- Establish a connection with Oracle Database
- Create Cursor objects
- Execute SQL statements
- Fetch records
- Manage transactions
- Close database resources
For example:
import cx_Oracle
imports the Oracle Database module used throughout the source tutorial.
Features of cx_Oracle
According to the document, the important features of cx_Oracle are:
- It is a Python extension module.
- It enables access to Oracle Database.
- It supports both Python 2 and Python 3.
- It can work with Oracle Database versions 9, 10, 11 and 12.
| Feature | Description |
|---|---|
| Module | cx_Oracle |
| Type | Python Extension Module |
| Purpose | Access Oracle Database from Python |
| Python Versions in Source | Python 2 and Python 3 |
| Oracle Versions in Source | 9, 10, 11 and 12 |
Oracle Versions Mentioned in the Document
The source document specifically mentions that cx_Oracle can work with the following Oracle Database versions:
Oracle 9 Oracle 10 Oracle 11 Oracle 12
Graphically:
cx_Oracle
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
Oracle 9 Oracle 10 Oracle 11
│
▼
Oracle 12
Note: These versions reflect the source document's original environment and should be understood as historical tutorial information.
Installing cx_Oracle
Before using cx_Oracle, it must be installed in the Python environment.
The document instructs us to install it from the Normal Command Prompt.
It should not be typed inside the Python Console.
Command Prompt
D:\python_classes>pip install cx_Oracle
The important installation command is:
pip install cx_Oracle
Where to Run the Installation Command?
Run:
pip install cx_Oracle
from the operating system's Command Prompt.
Correct
D:\python_classes>pip install cx_Oracle
Not the Python Console
>>> pip install cx_Oracle
pip install ... is a command-line installation command, not normal Python source code.
Installation Process
Open Command Prompt
│
▼
Run Installation Command
│
▼
pip install cx_Oracle
│
▼
pip Finds Package
│
▼
Package Downloaded
│
▼
Package Installed
│
▼
Installation Successful
Installation Command
main.py
No output captured.
Installation Output
The document shows installation output similar to the following:
Collecting cx_Oracle Downloading cx_Oracle-6.0.2-cp36-cp36m-win32.whl (100kB) 100% |-----------| 102kB 256kB/s Installing collected packages: cx-Oracle Successfully installed cx-Oracle-6.0.2
The important success message is:
Successfully installed cx-Oracle-6.0.2
This indicates that the package was installed successfully in the environment used by the source tutorial.
Understanding the Installation Output
Let us understand the major parts of the displayed installation output.
1. Collecting Package
Collecting cx_Oracle
pip starts locating the required package.
2. Downloading Package
Downloading cx_Oracle-6.0.2-cp36-cp36m-win32.whl
The required package file is downloaded.
3. Installing Package
Installing collected packages: cx-Oracle
The downloaded package is installed.
4. Successful Installation
Successfully installed cx-Oracle-6.0.2
The installation has completed successfully.
Understanding the Wheel File Name
The source installation output contains:
cx_Oracle-6.0.2-cp36-cp36m-win32.whl
This is the package file downloaded in the environment used by the original tutorial.
| Part | Meaning in the Source Environment |
|---|---|
cx_Oracle |
Package name |
6.0.2 |
Package version |
cp36 |
CPython 3.6 tag |
win32 |
32-bit Windows platform tag |
.whl |
Python wheel package |
You do not need to manually type this filename when using the normal pip install cx_Oracle command.
How to Test cx_Oracle Installation
After installation, we should verify whether the module is available in Python.
The source document uses:
help("modules")
for verification.
Open the Python Console and execute:
>>> help("modules")
Python displays the available modules.
We should check whether:
cx_Oracle
appears in that list.
Testing Command
main.py
No output captured.
Testing Installation Flow
Install cx_Oracle
│
▼
Open Python Console
│
▼
Run
help("modules")
│
▼
Python Displays Modules
│
▼
Search for cx_Oracle
│
▼
Is cx_Oracle Present?
/ \
Yes No
│ │
▼ ▼
Installation Check
Verified Installation
Expected Output
The output of:
help("modules")
contains a large list of modules.
The source document shows cx_Oracle among the available modules.
A partial representation of the output shown in the document is:
_multiprocessing _opcode _operator _osx_support _overlapped _pickle _pydecimal _pyio _random _sha1 _sha256 _sha3 _sha512 _signal _sitebuiltins _socket _sqlite3 _sre _ssl _stat ... csv ctypes cx_Oracle data datetime dbm decimal difflib dis distutils doctest dummy_threading durgamath easy_install ... parser pathlib pdb pick pickle pickletools pip pipes pkg_resources pkgutil platform plistlib polymorph ... urllib uu uuid
The important entry for this tutorial is:
cx_Oracle
How to Confirm Successful Installation
If cx_Oracle appears in the output of:
help("modules")
then the module is available to that Python environment.
help("modules")
│
▼
List of Installed / Available Modules
│
▼
cx_Oracle Found
│
▼
Module Installation Verified
Command Prompt vs Python Console
Two different environments are used during installation and testing.
| Environment | Command | Purpose |
|---|---|---|
| Command Prompt | pip install cx_Oracle |
Install the package |
| Python Console | help("modules") |
Check available Python modules |
Command Prompt
│
▼
pip install cx_Oracle
│
▼
Install Package
│
▼
Python Console
│
▼
help("modules")
│
▼
Verify Package
Alternative Simple Import Test
For practical testing, we can also try importing the module:
import cx_Oracle
If the module is installed correctly and available to the current Python environment, the import should complete without a module-not-found error.
For example:
>>> import cx_Oracle >>>
If Python immediately returns to the prompt without an import error, the module was found.
This is an additional practical verification method. The source document itself specifically demonstrates help("modules").
If cx_Oracle is Not Available
If Python cannot find the module, an error similar to the following may occur:
ModuleNotFoundError: No module named 'cx_Oracle'
This usually means that the package is not available in the Python environment currently running the program.
The basic relationship is:
Python Environment A
│
├── cx_Oracle installed
│
└── import cx_Oracle works
Python Environment B
│
├── cx_Oracle not installed
│
└── import cx_Oracle fails
Therefore, installation and program execution should use the intended Python environment.
Driver Communication Process
After installation, cx_Oracle can participate in the database communication process.
Step 1
Python Program
│
▼
Import cx_Oracle
│
▼
Step 2
Use cx_Oracle API
│
▼
Step 3
Driver Communicates
with Oracle
│
▼
Step 4
Oracle Executes
Database Operation
│
▼
Step 5
Result Returned
through Driver
│
▼
Python Program
The actual connection program will be covered in the next part.
Role of cx_Oracle in Python Database Programming
| Layer | Role |
|---|---|
| Python Program | Contains application logic and database calls |
cx_Oracle |
Provides the Python interface used to communicate with Oracle |
| Oracle Database | Stores data and executes supported database operations |
Application Logic
│
▼
Python
│
▼
cx_Oracle
│
▼
Oracle Database
Database Module vs Driver Concept
In this chapter, cx_Oracle is described as the Oracle Driver/Connector and as a Python extension module.
For learning purposes, remember the following flow:
Python Program
│
▼
Oracle Database Module / Driver
│
▼
cx_Oracle
│
▼
Oracle Database
The main purpose is to provide communication between Python and Oracle.
Complete Installation and Testing Flow
START
│
▼
Need Oracle Communication
│
▼
Driver Required
│
▼
cx_Oracle
│
▼
Open Command Prompt
│
▼
pip install cx_Oracle
│
▼
Package Installed
│
▼
Open Python Console
│
▼
help("modules")
│
▼
Search for cx_Oracle
│
┌───────┴───────┐
│ │
▼ ▼
Found Not Found
│ │
▼ ▼
Installation Recheck
Verified Environment /
Installation
│
▼
Ready for Oracle
Database Programming
│
▼
END
Installation and Testing Comparison
| Stage | Environment | Command | Result |
|---|---|---|---|
| Installation | Command Prompt | pip install cx_Oracle |
Installs the package |
| Verification in Source | Python Console | help("modules") |
Shows available modules |
| Simple Import Check | Python Console / Program | import cx_Oracle |
Checks whether the module can be imported |
Quick Revision
Working with Oracle Database
│
▼
Driver Required
│
▼
cx_Oracle
│
├── Python Extension Module
│
├── Oracle Access
│
├── Python 2 & 3
│
└── Oracle 9, 10, 11, 12
│
▼
Installation
│
▼
pip install cx_Oracle
│
▼
Testing
│
▼
help("modules")
│
▼
Find "cx_Oracle"
│
▼
Installation Verified
Summary
| Topic | Description |
|---|---|
| Driver / Connector | Translator between Python and Oracle Database |
| Oracle Driver in Source | cx_Oracle |
| Purpose | Converts communication between Python and Oracle Database |
| Module Type | Python extension module |
| Python Versions Mentioned | Python 2 and Python 3 |
| Oracle Versions Mentioned | 9, 10, 11 and 12 |
| Installation Command | pip install cx_Oracle |
| Where to Install | Normal Command Prompt |
| Installation Verification | help("modules") |
| Success Check | cx_Oracle should appear in the module list |
Important Points
- A Driver is required for communication between a Python program and Oracle Database.
- The Driver acts as a translator between Python calls and Database-specific calls.
- The Oracle Driver used in the source tutorial is
cx_Oracle. cx_Oracleis a Python extension module for accessing Oracle Database.- The source document states that
cx_Oraclesupports Python 2 and Python 3. - The source document mentions Oracle Database versions 9, 10, 11 and 12.
- The installation command shown in the document is
pip install cx_Oracle. - The installation command should be executed from the Command Prompt, not typed as normal code in the Python Console.
- The source verifies installation using
help("modules"). - If
cx_Oracleappears in the module list, the source considers installation successful.
Important Modern Note
The chapter uses cx_Oracle because that was the Oracle Python driver used when the original material was prepared.
For modern Python projects, Oracle's current Python driver is generally known as python-oracledb, imported as:
import oracledb
Therefore, keep this distinction in mind:
| Tutorial / Legacy Examples | Modern Oracle Python Development |
|---|---|
cx_Oracle |
python-oracledb |
import cx_Oracle |
import oracledb |
We will continue using cx_Oracle in this tutorial wherever required to preserve the programs and examples from the source document.
Part 3 - Final Concept
Python Program
│
▼
Needs Oracle Database
Communication
│
▼
Driver Required
│
▼
cx_Oracle
│
▼
Install Driver
│
▼
pip install cx_Oracle
│
▼
Test Installation
│
▼
help("modules")
│
▼
cx_Oracle Available
│
▼
Ready to Connect
│
▼
Oracle Database
Part 3 Completed
Next: Part 4 — App1: Program to Connect with Oracle Database and Print Its Version
Introduction
After installing the cx_Oracle driver successfully, the first Oracle Database application is to connect a Python program with Oracle Database and print the Oracle Database version.
This is a simple program, but it demonstrates the most basic database operation: establishing a connection.
This application demonstrates how to:
- Import the Oracle Database module
- Establish a connection with Oracle Database
- Store the Connection object
- Access the Oracle Database version
- Print the Database version
- Close the Database connection
Python Program
│
▼
Import cx_Oracle
│
▼
Connect to Oracle
│
▼
Get Database Version
│
▼
Print Version
│
▼
Close Connection
App1 — Program to Connect with Oracle Database and Print Its Version
The complete program given in the document is:
Complete Program
main.py
No output captured.
Program Output
The document shows the program being executed as:
D:\python_classes>py db1.py 11.2.0.2.0
Therefore, the Oracle Database version in the source example is:
11.2.0.2.0
This value depends on the Oracle Database server to which the Python program is connected.
Understanding the Program
The program contains only four main statements:
import cx_Oracle
con = cx_Oracle.connect('scott/tiger@localhost')
print(con.version)
con.close()
Let us understand every statement step by step.
Step 1 — Import the Module
The first statement is:
import cx_Oracle
This statement imports the cx_Oracle module into the Python program.
The cx_Oracle module enables communication between:
Python Program
│
▼
cx_Oracle
│
▼
Oracle Database
Without importing the required database module, the program cannot use functions such as:
cx_Oracle.connect()
Import Statement Explanation
| Part | Meaning |
|---|---|
import |
Python keyword used to import a module |
cx_Oracle |
Oracle Database driver/module used in the source tutorial |
import cx_Oracle
│
▼
Oracle Database functionality
becomes available to Python
Step 2 — Establish Connection
The second statement is:
con = cx_Oracle.connect('scott/tiger@localhost')
This statement establishes a connection between the Python program and the Oracle Database.
The connect() function is provided by the cx_Oracle module.
cx_Oracle.connect(...)
│
▼
Connect to Oracle
│
▼
Return Connection Object
│
▼
Store in con
connect() Function
The connect() function is used to create a connection with Oracle Database.
General Syntax
cx_Oracle.connect(database_information)
Program
cx_Oracle.connect('scott/tiger@localhost')
The returned Connection object is assigned to:
con
Connection Details
The source program uses the following connection information:
scott/tiger@localhost
It represents:
| Connection Detail | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database / Connection Location | localhost |
scott / tiger @ localhost │ │ │ │ │ └── Database connection location │ │ │ └── Password │ └── Username
What is localhost?
The program uses:
localhost
localhost refers to the local computer in this tutorial setup.
Therefore, the example assumes that the required Oracle Database service can be reached through the local machine configuration.
Python Program
│
▼
localhost
│
▼
Oracle Database
Connection Object
When the following statement executes:
con = cx_Oracle.connect('scott/tiger@localhost')
connect() returns a Connection object.
This object is stored in:
con
The Connection object represents the connection between Python and Oracle Database.
con
│
▼
Connection Object
│
▼
Oracle Database
Purpose of con
The variable:
con
contains a reference to the Oracle Connection object.
Through this object, we can perform operations such as:
- Access connection information
- Create a Cursor object
- Commit transactions
- Rollback transactions
- Close the connection
In this particular program, we use it for:
con.version con.close()
Step 3 — Print the Database Version
The third statement is:
print(con.version)
The version attribute of the Connection object returns the version of the connected Oracle Database.
The value is then passed to:
print()
so that it is displayed on the screen.
Understanding con.version
Consider:
con.version
Here:
| Part | Meaning |
|---|---|
con |
Oracle Connection object |
. |
Member-access operator |
version |
Attribute containing the connected Oracle Database version |
con.version │ │ │ └── Database version │ └── Connection object
How print(con.version) Works
con │ ▼ Oracle Connection Object │ ▼ Access version Attribute │ ▼ 11.2.0.2.0 │ ▼ print() │ ▼ 11.2.0.2.0
According to the document, the output is:
11.2.0.2.0
Understanding the Version Number
The source program displays:
11.2.0.2.0
This is the Oracle Database version reported by the connection used in the document.
The important concept is not to memorize this particular version number.
The important concept is:
con.version
returns the version information for the Oracle Database to which the program is connected.
If another Oracle Database version is used, the output can be different.
Step 4 — Close the Connection
The final statement is:
con.close()
After completing the Database operation, the connection is closed.
Closing the connection releases the Database resource associated with that connection.
Oracle Connection
│
▼
Operation Completed
│
▼
con.close()
│
▼
Connection Closed
Why Should We Close the Connection?
A Database connection is a resource.
After the application completes its required Database operations, the connection should be released.
Therefore, we use:
con.close()
This follows the resource-cleanup principle introduced in the standard Python Database Programming steps.
Open Connection
│
▼
Use Database
│
▼
Complete Operation
│
▼
Close Connection
Line-by-Line Program Explanation
| Line | Statement | Purpose |
|---|---|---|
| 1 | import cx_Oracle |
Imports the Oracle Database module |
| 2 | con = cx_Oracle.connect('scott/tiger@localhost') |
Establishes the Oracle Database connection |
| 3 | print(con.version) |
Displays the connected Oracle Database version |
| 4 | con.close() |
Closes the Database connection |
Program Execution Flow
START │ ▼ Import cx_Oracle │ ▼ cx_Oracle Module Available │ ▼ Call connect() │ ▼ Use scott/tiger@localhost │ ▼ Connect to Oracle Database │ ▼ Connection Successful │ ▼ Connection Object Stored in con │ ▼ Access con.version │ ▼ Print Oracle Database Version │ ▼ 11.2.0.2.0 │ ▼ Call con.close() │ ▼ Close Database Connection │ ▼ END
Program Flow
The simplified program flow given by the document is:
Import cx_Oracle
│
▼
Create Connection
│
▼
Print Database Version
│
▼
Close Connection
Methods and Attributes Used
| Method / Attribute | Purpose |
|---|---|
cx_Oracle.connect() |
Establishes a connection with Oracle Database |
con.version |
Returns the Oracle Database version |
con.close() |
Closes the Database connection |
connect() vs version vs close()
| Operation | Code | Purpose |
|---|---|---|
| Connect | cx_Oracle.connect(...) |
Creates a Database connection |
| Get Version | con.version |
Gets the connected Oracle Database version |
| Close | con.close() |
Releases the Database connection |
connect()
│
▼
Connection
│
▼
version
│
▼
Database Version
│
▼
close()
Why is Cursor Not Required in This Program?
In the standard Database Programming steps, we learned about creating a Cursor object:
cursor = con.cursor()
But this program does not execute any SQL statement.
It only accesses an attribute of the Connection object:
con.version
Therefore, no Cursor object is required for this particular program.
Need to Execute SQL?
│
├── Yes → Create Cursor
│
└── No
│
▼
Cursor may not
be required
Why commit() is Not Required
This program does not perform any DML operation such as:
- INSERT
- UPDATE
- DELETE
It only connects to Oracle and reads the Database version.
Therefore:
con.commit()
is not required.
Program │ ▼ Only Reads Version │ ▼ No Data Modification │ ▼ No commit() Required
Connection Success
If the connection information is correct and Oracle Database is available, this statement succeeds:
con = cx_Oracle.connect('scott/tiger@localhost')
The program can then execute:
print(con.version)
and display the Database version.
Valid Connection Details
+
Oracle Database Available
│
▼
Connection Established
│
▼
Version Displayed
Connection Failure
If the connection cannot be established, the program will not reach the version-printing step normally.
Possible causes in a real environment can include:
- Incorrect username
- Incorrect password
- Incorrect connection information
- Oracle Database service not available
- Required Oracle client/driver configuration missing
connect() │ ▼ Connection Successful? │ ┌─┴─┐ │ │ Yes No │ │ ▼ ▼ Print Error / Version Exception
Later examples in the document introduce try, except, and finally for safer Database programming.
Connection Object Lifecycle
cx_Oracle.connect(...)
│
▼
Connection Object Created
│
▼
Stored in con
│
▼
Use Connection
│
▼
con.version
│
▼
Operation Completed
│
▼
con.close()
│
▼
Connection Closed
Complete Program with Comments
main.py
No output captured.
Program Output with Explanation
D:\python_classes>py db1.py 11.2.0.2.0
Here:
| Output | Meaning |
|---|---|
D:\python_classes> |
Command Prompt location shown in the source example |
py db1.py |
Runs the Python program |
11.2.0.2.0 |
Oracle Database version returned by con.version |
Important Points
- Import the
cx_Oraclemodule before connecting to Oracle. - Use
cx_Oracle.connect()to establish the Database connection. - The source program uses
scottas the username. - The source program uses
tigeras the password. - The source program uses
localhostas the Database connection location. - The Connection object is stored in the variable
con. - The
versionattribute displays the Oracle Database version. - The document's example output is
11.2.0.2.0. - The actual version output depends on the Oracle Database being used.
- A Cursor is not required here because no SQL query is executed.
commit()is not required because the program does not modify Database data.- Always close the connection using
close()after completing Database operations.
Summary
| Step | Description |
|---|---|
| Import Module | import cx_Oracle |
| Connect Database | cx_Oracle.connect('scott/tiger@localhost') |
| Store Connection | con = ... |
| Print Version | print(con.version) |
| Close Connection | con.close() |
The complete program is:
import cx_Oracle
con = cx_Oracle.connect('scott/tiger@localhost')
print(con.version)
con.close()
Output shown in the document:
11.2.0.2.0
Quick Revision
App1
│
▼
import cx_Oracle
│
▼
cx_Oracle.connect()
│
▼
'scott/tiger@localhost'
│
▼
Connection Object
│
▼
con
│
├───────────────┐
│ │
▼ ▼
con.version con.close()
│ │
▼ ▼
11.2.0.2.0 Connection
Closed
Part 4 - Final Concept
START
│
▼
import cx_Oracle
│
▼
cx_Oracle.connect(
'scott/tiger@localhost'
)
│
▼
Connection Created
│
▼
Stored in "con"
│
▼
con.version
│
▼
print(con.version)
│
▼
11.2.0.2.0
│
▼
con.close()
│
▼
Connection Closed
│
▼
END
Part 4 Completed
Next: Part 5 — App2: Program to Create Employees Table in Oracle Database
Introduction
In this application, we will create a table named employees in the Oracle Database.
The employees table contains the following columns:
eno→ Employee Numberename→ Employee Nameesal→ Employee Salaryeaddr→ Employee Address
This application also demonstrates how to use:
tryexceptfinallycursor()execute()rollback()close()
These concepts help us perform Database operations safely.
Python Program
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Execute CREATE TABLE
│
▼
Create employees Table
Employees Table Structure
The program creates the following employees table:
| Column | Data Type |
|---|---|
eno |
number |
ename |
varchar2(10) |
esal |
number(10,2) |
eaddr |
varchar2(10) |
employees +---------------------------+ | eno : number | | ename : varchar2(10) | | esal : number(10,2) | | eaddr : varchar2(10) | +---------------------------+
Understanding the Columns
| Column | Purpose | Data Type |
|---|---|---|
eno |
Stores employee number | number |
ename |
Stores employee name | varchar2(10) |
esal |
Stores employee salary | number(10,2) |
eaddr |
Stores employee address | varchar2(10) |
App2 — Program to Create Employees Table
The complete program given in the document is:
Complete Program
main.py
No output captured.
Understanding the Program
The program performs the following operations:
Import cx_Oracle
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Execute CREATE TABLE
│
▼
Create employees Table
│
▼
Display Success Message
│
▼
Close Resources
If an Oracle Database error occurs, the program handles it using the except block.
Step 1 — Import the Module
The first statement is:
import cx_Oracle
The cx_Oracle module is imported to communicate with the Oracle Database.
Python │ ▼ cx_Oracle │ ▼ Oracle Database
Step 2 — try Block
The Database operations are written inside a try block:
try:
...
The try block contains the code that may generate an Oracle Database error.
In this application, the following operations are performed inside try:
- Connect to Oracle Database
- Create the Cursor object
- Execute the CREATE TABLE statement
- Display the success message
try │ ├── Connect ├── Create Cursor ├── Execute SQL └── Print Success Message
Step 3 — Create Database Connection
The connection is created using:
con = cx_Oracle.connect('scott/tiger@localhost')
A Connection object is created using the following details:
| Detail | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The returned Connection object is stored in:
con
Connection Flow
cx_Oracle.connect(
'scott/tiger@localhost'
)
│
▼
Connect to Oracle
│
▼
Connection Object
│
▼
con
Step 4 — Create Cursor Object
After establishing the Database connection, the program creates a Cursor object:
cursor = con.cursor()
The Cursor object is required to execute SQL statements.
The returned Cursor object is stored in:
cursor
Connection Object
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
cursor
Why is a Cursor Required?
In Part 4, we only printed the Database version, so a Cursor was not required.
In this application, however, we need to execute an SQL statement:
CREATE TABLE employees
Therefore, a Cursor object is required.
Need to Execute SQL?
│
▼
Yes
│
▼
Create Cursor Object
│
▼
cursor = con.cursor()
Step 5 — Execute CREATE TABLE Query
The program executes the following SQL statement:
cursor.execute(
"create table employees("
"eno number,"
"ename varchar2(10),"
"esal number(10,2),"
"eaddr varchar2(10))"
)
The execute() method executes the SQL statement that creates the employees table.
SQL Query
If we write the SQL statement separately, it looks like this:
create table employees(
eno number,
ename varchar2(10),
esal number(10,2),
eaddr varchar2(10)
)
This SQL command creates a table named:
employees
with four columns.
Understanding CREATE TABLE
CREATE TABLE is an SQL statement used to create a new table in a Database.
General Syntax
CREATE TABLE table_name(
column1 datatype,
column2 datatype,
...
)
In this Program
CREATE TABLE employees(
eno number,
ename varchar2(10),
esal number(10,2),
eaddr varchar2(10)
)
Understanding eno
eno number
eno represents the Employee Number.
Its data type is:
number
Therefore, it is used to store numeric employee numbers.
Understanding ename
ename varchar2(10)
ename represents the Employee Name.
Its data type is:
varchar2(10)
It stores character data with a maximum size of 10 characters in the table definition used by the tutorial.
Understanding esal
esal number(10,2)
esal represents Employee Salary.
The source program uses:
number(10,2)
This allows numeric salary values with decimal precision according to the Oracle numeric definition.
Understanding eaddr
eaddr varchar2(10)
eaddr represents Employee Address.
Its data type is:
varchar2(10)
It stores character data with the size specified in the source table definition.
How execute() Works
cursor │ ▼ execute(SQL) │ ▼ CREATE TABLE employees │ ▼ Oracle Database │ ▼ employees Table Created
The Cursor object sends the SQL statement to Oracle Database for execution.
Step 6 — Display Success Message
After executing the CREATE TABLE statement, the program executes:
print("Table created successfully")
If the SQL statement executes successfully, the following message is displayed:
Table created successfully
This confirms that the program reached the success statement after executing the table-creation query.
Exception Handling
The program uses:
try except finally
for safe Database programming.
try
│
▼
Database Operation
│
▼
Error?
/ \
No Yes
│ │
▼ ▼
Success except
│ │
└───┬────┘
▼
finally
│
▼
Close Resources
except Block
The exception block is:
except cx_Oracle.DatabaseError as e:
If an Oracle Database error occurs inside the try block, execution moves to this except block.
The error object is stored in:
e
| Part | Meaning |
|---|---|
cx_Oracle.DatabaseError |
Oracle Database-related exception class used in the program |
as e |
Stores the exception object in variable e |
Rollback
Inside the except block, the program checks:
if con:
con.rollback()
If the Connection object exists, the program calls:
con.rollback()
rollback() is used to roll back temporary Database changes when an error occurs.
Database Error
│
▼
Is con Available?
│
▼
Yes
│
▼
con.rollback()
│
▼
Rollback Changes
Why Check if con Exists?
The program uses:
if con:
con.rollback()
The condition checks whether a usable Connection object is available before attempting to call rollback().
if con │ ├── True → con.rollback() │ └── False → Skip rollback()
Display Error Message
After rollback, the program executes:
print("There is a problem with sql", e)
This displays the SQL-related error information stored in:
e
The general output structure is:
There is a problem with sql <Oracle Database error>
Example: Table Already Exists
If the employees table already exists, executing the CREATE TABLE statement again can result in an Oracle Database error.
CREATE TABLE employees
│
▼
Does employees already exist?
/ \
No Yes
│ │
▼ ▼
Create DatabaseError
Table │
▼
except
The exact Oracle error depends on the Database environment.
finally Block
The program contains:
finally:
The finally block executes whether an exception occurs or not.
It is used here to close Database resources.
try
│
├── Success ───┐
│ │
└── Error ─────┤
▼
finally
│
▼
Close Resources
Close Cursor
Inside the finally block:
if cursor:
cursor.close()
If the Cursor object exists, it is closed using:
cursor.close()
This releases the Cursor resource.
Close Connection
After closing the Cursor, the program closes the Connection:
if con:
con.close()
The Database connection is closed using:
con.close()
This releases the Database connection resource.
Why Cursor is Closed Before Connection
The Cursor was created after the Connection:
Connection │ ▼ Cursor
Resources are normally closed in the reverse order:
Cursor │ ▼ Connection
Therefore, the program performs:
cursor.close() con.close()
Complete try-except-finally Flow
START
│
▼
Import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute CREATE TABLE
│
▼
SQL Successful?
│
┌┴──────────────┐
│ │
Yes No
│ │
▼ ▼
Print DatabaseError
"Table created │
successfully" ▼
│ except
│ │
│ if con:
│ rollback()
│ │
│ Print Error
│ │
└───────┬───────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Program Flow
The program flow can be represented as:
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute CREATE TABLE SQL
│
▼
Table Created Successfully
│
▼
Exception?
/ \
No Yes
│ │
▼ ▼
Close Rollback
Resources Print Error
│ │
└────┬─────┘
▼
Program Ends
Successful Execution Flow
START │ ▼ Connect to Oracle │ ▼ Create Cursor │ ▼ Execute CREATE TABLE │ ▼ Table Created │ ▼ Print Success Message │ ▼ finally │ ▼ Close Cursor │ ▼ Close Connection │ ▼ END
Error Execution Flow
START │ ▼ Database Operation │ ▼ DatabaseError │ ▼ except │ ▼ if con │ ▼ rollback() │ ▼ Print Error │ ▼ finally │ ▼ Close Cursor │ ▼ Close Connection │ ▼ END
Methods Used
| Method | Purpose |
|---|---|
connect() |
Creates a Database connection |
cursor() |
Creates a Cursor object |
execute() |
Executes the SQL query |
rollback() |
Cancels temporary changes if an error occurs |
cursor.close() |
Closes the Cursor |
con.close() |
Closes the Database connection |
Important Objects Used
| Object / Variable | Purpose |
|---|---|
con |
Stores the Oracle Connection object |
cursor |
Stores the Cursor object used to execute SQL |
e |
Stores the Oracle Database exception object |
CREATE TABLE vs execute()
| Concept | Purpose |
|---|---|
CREATE TABLE |
SQL statement that defines and creates the table |
cursor.execute() |
Python Database API operation used to send the SQL statement for execution |
Python │ ▼ cursor.execute() │ ▼ CREATE TABLE employees(...) │ ▼ Oracle Database │ ▼ employees Table
Complete Program with Comments
main.py
No output captured.
Important Points
- The program creates a table named
employees. - The table contains four columns:
eno,ename,esal, andeaddr. - The
cx_Oraclemodule is used to communicate with Oracle Database. - Use
connect()to establish the Database connection. - Use
cursor()before executing SQL statements. - The
execute()method executes theCREATE TABLEquery. - The program uses
try-except-finallyfor safe execution. cx_Oracle.DatabaseErrorhandles Oracle Database-related errors.- If an SQL error occurs,
rollback()is executed when a connection is available. - The error object is stored in
e. - The
finallyblock executes whether an exception occurs or not. - The Cursor and Connection are closed inside the
finallyblock. - The Cursor is closed before the Connection.
Summary
| Topic | Description |
|---|---|
| Table Name | employees |
| Columns | eno, ename, esal, eaddr |
| SQL Statement | CREATE TABLE |
| Connection | cx_Oracle.connect() |
| Cursor Method | cursor() |
| Execution Method | execute() |
| Exception Class | cx_Oracle.DatabaseError |
| Rollback Method | rollback() |
| Resource Cleanup | cursor.close() and con.close() |
Quick Revision
App2
│
▼
import cx_Oracle
│
▼
try
│
▼
connect()
│
▼
con
│
▼
cursor()
│
▼
cursor
│
▼
execute()
│
▼
CREATE TABLE employees
│
▼
Success?
│
├── Yes → "Table created successfully"
│
└── No → DatabaseError
│
▼
rollback()
│
▼
Print Error
│
▼
finally
│
▼
cursor.close()
│
▼
con.close()
Part 5 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Connect to Oracle Database
│
▼
Create Cursor
│
▼
Execute CREATE TABLE Query
│
▼
employees Table
│
┌──────┴──────┐
│ │
Success Error
│ │
▼ ▼
Print Success DatabaseError
│
▼
rollback()
│
▼
Print Error
│ │
└──────┬──────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 5 Completed
Next: Part 6 — App3: Program to Drop Employees Table from Oracle Database
Introduction
In the previous application, we created an employees table in Oracle Database.
Now we will learn how to drop the employees table from Oracle Database using a Python program.
To remove an existing table, SQL provides the:
DROP TABLE
command.
This application demonstrates:
- Connecting Python with Oracle Database
- Creating a Cursor object
- Executing a
DROP TABLESQL statement - Handling Database errors
- Using
try-except-finally - Using
rollback() - Closing Cursor and Connection resources
Python Program
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Execute DROP TABLE
│
▼
employees Table Removed
What is DROP TABLE?
DROP TABLE is an SQL command used to remove an existing table from a Database.
General Syntax
DROP TABLE table_name
For the employees table:
DROP TABLE employees
After this statement is executed successfully, the employees table is removed from the Database.
CREATE TABLE vs DROP TABLE
| SQL Command | Purpose |
|---|---|
CREATE TABLE |
Creates a new table |
DROP TABLE |
Removes an existing table |
CREATE TABLE employees
│
▼
employees Created
DROP TABLE employees
│
▼
employees Removed
App3 — Program to Drop Employees Table
The program follows the same Database-programming structure used in the previous application.
The important SQL statement in this application is:
drop table employees
Complete Program
main.py
No output captured.
Program Structure
The program contains four major sections:
- Import the Oracle module
- Perform Database operations inside
try - Handle Database errors inside
except - Close resources inside
finally
import cx_Oracle
│
▼
try
│
├── Connect
├── Create Cursor
├── DROP TABLE
└── Print Success
│
▼
except
│
├── rollback()
└── Print Error
│
▼
finally
│
├── Close Cursor
└── Close Connection
Step 1 — Import cx_Oracle
The program starts with:
import cx_Oracle
This imports the Oracle Database module used throughout the source tutorial.
It provides the functionality required to:
- Connect to Oracle Database
- Create Cursor objects
- Execute SQL statements
- Handle Oracle Database errors
- Manage transactions
Python Program
│
▼
cx_Oracle
│
▼
Oracle Database
Step 2 — try Block
The Database operations are placed inside:
try:
The try block contains code that may generate a Database-related exception.
In this program, it contains:
con = cx_Oracle.connect(...)
cursor = con.cursor()
cursor.execute("drop table employees")
print("Table dropped successfully")
Step 3 — Establish Connection
The program connects to Oracle Database using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection information is:
| Part | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database / Location | localhost |
The returned Connection object is stored in:
con
Connection Flow
cx_Oracle.connect(
'scott/tiger@localhost'
)
│
▼
Oracle Database
│
▼
Connection Established
│
▼
Connection Object
│
▼
con
Step 4 — Create Cursor Object
After creating the Connection object, the program creates a Cursor object:
cursor = con.cursor()
The Cursor is required because we need to execute an SQL statement.
Connection
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
cursor
Why is Cursor Required?
The SQL command:
DROP TABLE employees
must be sent to Oracle Database for execution.
The Cursor object performs this operation.
Python │ ▼ Cursor │ ▼ SQL Statement │ ▼ Oracle Database
Therefore:
cursor = con.cursor()
is required before calling execute().
Step 5 — Execute DROP TABLE Statement
The most important statement in this application is:
cursor.execute("drop table employees")
The execute() method sends the SQL statement to Oracle Database.
The SQL statement is:
drop table employees
Its purpose is to remove the employees table.
Understanding cursor.execute()
Consider:
cursor.execute("drop table employees")
| Part | Meaning |
|---|---|
cursor |
Cursor object |
execute() |
Method used to execute an SQL statement |
drop table employees |
SQL statement being executed |
DROP TABLE Execution
cursor │ ▼ execute() │ ▼ "drop table employees" │ ▼ Oracle Database │ ▼ Locate employees Table │ ▼ Drop Table │ ▼ employees Removed
Before and After DROP TABLE
Before
Oracle Database
│
▼
+----------------------+
| employees |
+----------------------+
| eno |
| ename |
| esal |
| eaddr |
+----------------------+
After
Oracle Database
│
▼
employees table
no longer exists
DROP TABLE removes the table definition and its associated table data according to Oracle's DROP TABLE behavior.
Step 6 — Print Success Message
If the SQL statement executes successfully, the next statement is:
print("Table dropped successfully")
Therefore, the success message is:
Table dropped successfully
This indicates that execution reached the success statement after the DROP operation.
Successful Program Flow
Connect to Oracle
│
▼
Create Cursor
│
▼
DROP TABLE employees
│
▼
Table Dropped
│
▼
Print
"Table dropped successfully"
│
▼
finally
│
▼
Close Resources
Step 7 — Handle DatabaseError
If an Oracle Database-related error occurs, the program uses:
except cx_Oracle.DatabaseError as e:
The exception object is stored in:
e
This allows the program to display information about the Database error.
DatabaseError
cx_Oracle.DatabaseError is the exception class used by the source program for Database-related problems.
try
│
▼
Database Operation
│
▼
Database Error?
│
├── No → Continue
│
└── Yes
│
▼
cx_Oracle.DatabaseError
│
▼
e
Possible Error — Table Does Not Exist
One possible problem is attempting to drop the employees table when it does not exist.
DROP TABLE employees
│
▼
Does employees exist?
/ \
Yes No
│ │
▼ ▼
Drop Database
Table Error
When such a Database error occurs, control moves to the except block.
Step 8 — rollback()
The except block contains:
if con:
con.rollback()
If a Connection object is available, the program calls:
con.rollback()
The source program follows the same exception-handling pattern used in the previous application.
DatabaseError
│
▼
if con
│
▼
con.rollback()
Important Oracle DDL Note
DROP TABLE is a DDL (Data Definition Language) operation.
Oracle performs implicit transaction handling around many DDL statements.
Therefore, although the source program calls:
con.rollback()
inside its general Database-error handler, you should not interpret this as meaning that a successfully executed Oracle DROP TABLE can normally be undone using rollback().
This is an important distinction:
| Operation Type | Examples | Typical Transaction Handling |
|---|---|---|
| DML | INSERT, UPDATE, DELETE | commit() / rollback() |
| DDL | CREATE TABLE, DROP TABLE | Oracle normally performs implicit commits around successful DDL |
Step 9 — Print Error
After the rollback check, the program executes:
print("There is a problem with sql", e)
This prints the message:
There is a problem with sql
along with the actual Oracle Database exception information stored in e.
Error Execution Flow
cursor.execute(
"drop table employees"
)
│
▼
Database Error
│
▼
except cx_Oracle.DatabaseError as e
│
▼
if con
│
▼
con.rollback()
│
▼
Print
"There is a problem with sql"
+
Error Information
│
▼
finally
Step 10 — finally Block
The program uses:
finally:
The finally block is used for resource cleanup.
It executes whether:
- The table is dropped successfully
- A Database error occurs
try
│
┌──────┴──────┐
│ │
Success Error
│ │
│ except
│ │
└──────┬──────┘
▼
finally
│
▼
Close Resources
Close Cursor
The program checks whether the Cursor exists:
if cursor:
cursor.close()
If it exists, the Cursor is closed.
cursor │ ▼ cursor.close() │ ▼ Cursor Resource Released
Close Connection
The Connection is then closed:
if con:
con.close()
If a Connection object exists:
con.close()
releases the Database connection.
Resource Closing Order
The resources were created in this order:
1. Connection 2. Cursor
They are closed in reverse order:
1. Cursor 2. Connection
| Opening | Closing |
|---|---|
| Connection | Cursor |
| Cursor | Connection |
Complete Program Execution Flow
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
execute("drop table employees")
│
┌─────┴─────┐
│ │
Success Error
│ │
▼ ▼
employees DatabaseError
Dropped │
│ ▼
│ if con
│ │
│ ▼
│ rollback()
│ │
▼ ▼
Print Success Print Error
│ │
└─────┬─────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Line-by-Line Explanation
| Statement | Purpose |
|---|---|
import cx_Oracle |
Imports Oracle Database support |
try: |
Starts protected Database operations |
con = cx_Oracle.connect(...) |
Establishes the Database connection |
cursor = con.cursor() |
Creates a Cursor object |
cursor.execute("drop table employees") |
Drops the employees table |
print("Table dropped successfully") |
Displays the success message |
except cx_Oracle.DatabaseError as e: |
Handles Database errors |
con.rollback() |
Performs rollback as part of the source's general error-handling pattern |
print(..., e) |
Displays error information |
finally: |
Runs resource-cleanup code |
cursor.close() |
Closes the Cursor |
con.close() |
Closes the Connection |
Complete Program with Comments
main.py
No output captured.
App2 vs App3
| Feature | App2 | App3 |
|---|---|---|
| Purpose | Create employees table | Drop employees table |
| SQL | CREATE TABLE |
DROP TABLE |
| Connection | connect() |
connect() |
| Cursor | cursor() |
cursor() |
| Execute SQL | execute() |
execute() |
| Error Handling | DatabaseError |
DatabaseError |
| Cleanup | finally |
finally |
Important Methods and Statements
| Method / Statement | Purpose |
|---|---|
cx_Oracle.connect() |
Connects Python to Oracle Database |
con.cursor() |
Creates the Cursor |
cursor.execute() |
Executes the DROP TABLE statement |
con.rollback() |
Used by the source's Database-error handling pattern |
cursor.close() |
Closes the Cursor |
con.close() |
Closes the Database connection |
Important Notes
DROP TABLEis used to remove an existing table.- The source application drops the
employeestable. - A Database connection is established before executing the SQL statement.
- A Cursor object is required to execute the
DROP TABLEstatement. - The SQL statement is executed using
cursor.execute(). - If the operation succeeds, the program prints
Table dropped successfully. - The program handles Oracle Database errors using
cx_Oracle.DatabaseError. - The exception object is stored in variable
e. - The source uses
con.rollback()in its common Database-error handling pattern. DROP TABLEis DDL. In Oracle, successful DDL normally involves implicit commit behavior, so a successful DROP should not be treated like ordinary DML that can simply be undone withrollback().- The
finallyblock is used to release Database resources. - The Cursor is closed before the Connection.
- Dropping a table removes the table itself, so this operation should be performed carefully.
Summary
| Topic | Description |
|---|---|
| Application | App3 |
| Purpose | Drop employees table |
| SQL Command | DROP TABLE employees |
| Connection | cx_Oracle.connect() |
| Cursor | con.cursor() |
| Execution | cursor.execute() |
| Exception | cx_Oracle.DatabaseError |
| Error Handling | rollback() pattern used in source |
| Cleanup | finally |
| Close Cursor | cursor.close() |
| Close Connection | con.close() |
Quick Revision
App3
│
▼
import cx_Oracle
│
▼
try
│
▼
connect()
│
▼
cursor()
│
▼
execute()
│
▼
DROP TABLE employees
│
▼
Successful?
│
├── Yes
│ │
│ ▼
│ Table dropped successfully
│
└── No
│
▼
DatabaseError
│
▼
rollback()
│
▼
Print Error
│
▼
finally
│
▼
cursor.close()
│
▼
con.close()
Part 6 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
cursor.execute(
"drop table employees"
)
│
┌────────┴────────┐
│ │
Success Error
│ │
▼ ▼
employees Table DatabaseError
Dropped │
│ ▼
│ rollback()
▼ │
Print Success ▼
Print Error
│ │
└────────┬────────┘
▼
finally
│
▼
cursor.close()
│
▼
con.close()
│
▼
END
Part 6 Completed
Next: Part 7 — App4: Insert a Single Row into Employees Table
Introduction
In this application, we will insert one record into the employees table.
This program demonstrates:
- Inserting a single row into a table
- Using the
INSERTSQL statement - Using the
commit()method - Using
rollback()when an error occurs - Using
try,except, andfinallyblocks
According to the document, while performing DML operations such as Insert, Update, and Delete, we have to use commit() so that the changes are permanently reflected in the Database.
Python Program
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Execute INSERT
│
▼
commit()
│
▼
Record Saved
What is a DML Operation?
DML stands for:
Data Manipulation Language
DML statements are used to manipulate the data stored inside Database tables.
The document gives the following examples:
INSERTUPDATEDELETE
| DML Operation | Purpose |
|---|---|
INSERT |
Add new records |
UPDATE |
Modify existing records |
DELETE |
Remove existing records |
DML and Transaction
For DML operations, changes remain part of the current transaction until they are committed.
DML Operation
│
▼
INSERT / UPDATE / DELETE
│
▼
Temporary Transaction Changes
│
├───────────────┐
│ │
▼ ▼
commit() rollback()
│ │
▼ ▼
Save Changes Cancel Changes
Therefore, two important transaction methods are:
commit() rollback()
App4 — Program to Insert a Single Row
The program inserts the following employee record:
| Employee Number | Employee Name | Salary | Address |
|---|---|---|---|
| 100 | Durga | 1000 | Hyd |
The SQL statement used is:
INSERT INTO employees VALUES(100,'Durga',1000,'Hyd');
Complete Program
main.py
No output captured.
Understanding the Program
The program follows these main steps:
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute INSERT Query
│
▼
commit()
│
▼
Record Saved
│
▼
Print Success Message
│
▼
Close Resources
If an Oracle Database error occurs, the program uses rollback() and displays the error.
Step 1 — Import the Module
The program starts with:
import cx_Oracle
The cx_Oracle module is imported to communicate with Oracle Database.
Python Program
│
▼
cx_Oracle
│
▼
Oracle Database
Step 2 — Establish Database Connection
The connection is established using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection details used in the document are:
| Detail | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The Connection object is stored in:
con
Connection Execution
cx_Oracle.connect(
'scott/tiger@localhost'
)
│
▼
Connect to Oracle Database
│
▼
Connection Object
│
▼
con
Step 3 — Create Cursor Object
The Cursor object is created using:
cursor = con.cursor()
The Cursor object is required to execute SQL statements.
Connection Object
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
cursor
In this program, the Cursor executes the INSERT statement.
Step 4 — Execute INSERT Query
The program executes:
cursor.execute(
"insert into employees values(100,'Durga',1000,'Hyd')"
)
The SQL statement is:
INSERT INTO employees VALUES(100,'Durga',1000,'Hyd');
This statement inserts one row into the employees table.
INSERT Statement Syntax
The general SQL syntax is:
INSERT INTO table_name VALUES(value1, value2, value3, ...);
In this application:
INSERT INTO employees VALUES(100,'Durga',1000,'Hyd');
| Part | Meaning |
|---|---|
INSERT INTO |
SQL command used to insert data |
employees |
Target table |
VALUES |
Specifies the values for the new record |
Inserted Values
The inserted values are:
| Column | Value |
|---|---|
eno |
100 |
ename |
Durga |
esal |
1000 |
eaddr |
Hyd |
employees +-----+-------+------+-------+ | eno | ename | esal | eaddr | +-----+-------+------+-------+ | 100 | Durga | 1000 | Hyd | +-----+-------+------+-------+
How execute() Inserts the Record
cursor │ ▼ execute() │ ▼ INSERT INTO employees VALUES(100,'Durga',1000,'Hyd') │ ▼ Oracle Database │ ▼ employees Table │ ▼ New Row Added to Transaction
At this stage, the transaction must be committed to save the change permanently.
Step 5 — Commit the Transaction
After executing the INSERT statement, the program calls:
con.commit()
The commit() method permanently saves the inserted record in the Database.
INSERT Record
│
▼
Transaction Change
│
▼
con.commit()
│
▼
Change Saved
What is commit()?
commit() is a transaction-management method.
It is called using the Connection object:
con.commit()
Its purpose is to make the current transaction changes permanent.
| Method | Purpose |
|---|---|
commit() |
Permanently saves transaction changes |
Why is commit() Required?
The source document gives an important rule:
While performing DML operations such as insert, update and delete, commit() has to be used so that the results are reflected in the Database.
In this program:
cursor.execute(INSERT...)
│
▼
Record Inserted in Transaction
│
▼
con.commit()
│
▼
Record Permanently Saved
Therefore, commit() is an important part of this application.
Without commit()
If we execute a DML statement but do not commit the transaction, the change has not been permanently committed by that transaction.
cursor.execute(INSERT...)
│
▼
Transaction Changed
│
▼
No commit()
│
▼
Change Not Permanently Committed
That is why the source emphasizes:
con.commit()
Step 6 — Display Success Message
After committing the transaction, the program executes:
print("Record Inserted Successfully")
The output is:
Record Inserted Successfully
This indicates that the INSERT operation and commit() completed before the success message was reached.
Successful Execution
INSERT Query
│
▼
Record Added
│
▼
commit()
│
▼
Record Saved
│
▼
print()
│
▼
Record Inserted Successfully
Exception Handling
The program handles Database errors using:
except cx_Oracle.DatabaseError as e:
If an Oracle Database error occurs inside the try block, execution moves to the except block.
The exception object is stored in:
e
try
│
▼
Database Operation
│
▼
Error?
├── No → Continue
│
└── Yes
│
▼
DatabaseError
│
▼
e
Rollback
Inside the exception handler:
if con:
con.rollback()
If the Connection object is available, the program calls:
con.rollback()
If an SQL error occurs before the transaction is committed, rollback() cancels the pending transaction changes.
SQL Error
│
▼
if con
│
▼
rollback()
│
▼
Pending Changes Cancelled
commit() vs rollback()
| commit() | rollback() |
|---|---|
| Saves transaction changes | Cancels uncommitted transaction changes |
| Makes successful DML changes permanent | Used when pending changes should be undone |
con.commit() |
con.rollback() |
DML Operation
│
▼
Transaction
/ \
/ \
▼ ▼
Successful Error
│ │
▼ ▼
commit() rollback()
│ │
▼ ▼
Save Cancel
Display Error Message
After rollback, the program executes:
print("There is a problem with sql", e)
This displays:
There is a problem with sql
along with the Oracle Database error information stored in e.
Finally Block
The program uses:
finally:
The finally block executes whether an exception occurs or not.
Its purpose is to release Database resources.
try
│
┌─────┴─────┐
│ │
Success Error
│ │
│ except
│ │
└─────┬─────┘
▼
finally
│
▼
Close Resources
Close Cursor
The program checks:
if cursor:
cursor.close()
If the Cursor object exists, it is closed using:
cursor.close()
This releases the Cursor resource.
Close Connection
The program then checks:
if con:
con.close()
If the Connection object exists, it is closed using:
con.close()
This releases the Database connection.
Resource Cleanup
The resources are opened in this order:
Connection
│
▼
Cursor
They are closed in reverse order:
Cursor
│
▼
Connection
Therefore:
cursor.close() con.close()
Complete Successful Execution Flow
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute INSERT Query
│
▼
INSERT INTO employees
VALUES(100,'Durga',1000,'Hyd')
│
▼
Record Added
│
▼
con.commit()
│
▼
Record Permanently
Saved
│
▼
"Record Inserted Successfully"
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Complete Error Execution Flow
START
│
▼
Execute INSERT
│
▼
SQL Error Occurs
│
▼
cx_Oracle.DatabaseError as e
│
▼
if con
│
▼
con.rollback()
│
▼
Cancel Pending Changes
│
▼
Print SQL Error
│
▼
finally
│
▼
cursor.close()
│
▼
con.close()
│
▼
END
Program Flow
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute INSERT Query
│
▼
Commit Changes
│
▼
Record Inserted Successfully
│
▼
Exception?
┌──┴──┐
│ │
No Yes
│ │
▼ ▼
Close Rollback
Resources Print Error
│ │
└──┬──┘
▼
Program Ends
Line-by-Line Explanation
| Statement | Purpose |
|---|---|
import cx_Oracle |
Imports the Oracle Database module |
try: |
Starts protected Database operations |
cx_Oracle.connect(...) |
Connects to Oracle Database |
con.cursor() |
Creates the Cursor object |
cursor.execute(...) |
Executes the INSERT statement |
con.commit() |
Permanently saves the inserted record |
print(...) |
Displays the success message |
except cx_Oracle.DatabaseError as e: |
Handles Oracle Database errors |
con.rollback() |
Cancels pending changes if an error occurs |
finally: |
Runs resource-cleanup code |
cursor.close() |
Closes the Cursor |
con.close() |
Closes the Connection |
Methods Used
| Method | Purpose |
|---|---|
connect() |
Creates a connection with Oracle Database |
cursor() |
Creates a Cursor object |
execute() |
Executes the INSERT SQL statement |
commit() |
Permanently saves the inserted record |
rollback() |
Cancels temporary changes if an error occurs |
close() |
Closes the Cursor and Connection |
Important Note from the Document
While performing DML Operations (insert | update | delete), compulsory we have to use commit() method, then only the results will be reflected in the database.
In simple words:
INSERT UPDATE DELETE │ ▼ DML Operations │ ▼ Perform Changes │ ▼ commit() │ ▼ Save Changes Permanently
The tutorial therefore explicitly calls:
con.commit()
after the successful INSERT operation.
Important Points
- The application inserts one employee record into the
employeestable. - The SQL operation used is
INSERT. INSERTis a DML operation.- The inserted employee number is
100. - The inserted employee name is
Durga. - The inserted salary is
1000. - The inserted address is
Hyd. - The Cursor executes the INSERT statement using
execute(). - The program uses
con.commit()after successful insertion. commit()permanently saves the transaction changes.- If an SQL error occurs before commit, the program uses
rollback(). rollback()cancels pending transaction changes.- The program catches Oracle Database errors using
cx_Oracle.DatabaseError. - The
finallyblock executes whether an error occurs or not. - The Cursor and Connection are closed in the
finallyblock. - The Cursor is closed before the Connection.
Summary
| Topic | Description |
|---|---|
| Application | App4 |
| SQL Operation | Insert |
| Table Name | employees |
| SQL Statement | INSERT INTO employees VALUES(100,'Durga',1000,'Hyd') |
| Inserted Employee | (100, 'Durga', 1000, 'Hyd') |
| Execution Method | execute() |
| Required Transaction Method | commit() |
| Error Handling | rollback() |
| Exception | cx_Oracle.DatabaseError |
| Resource Cleanup | cursor.close() and con.close() |
Quick Revision
App4 │ ▼ INSERT Single Row │ ▼ (100, 'Durga', 1000, 'Hyd') │ ▼ cursor.execute() │ ▼ Transaction Changed │ ▼ con.commit() │ ▼ Record Saved │ ▼ "Record Inserted Successfully" If Error │ ▼ DatabaseError │ ▼ rollback() │ ▼ Cancel Pending Changes Finally │ ▼ cursor.close() │ ▼ con.close()
Part 7 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute INSERT Query
│
▼
INSERT INTO employees VALUES
(100,'Durga',1000,'Hyd')
│
▼
Transaction Changed
│
┌───────┴───────┐
│ │
Success Error
│ │
▼ ▼
commit() DatabaseError
│ │
▼ ▼
Save Record rollback()
│ │
▼ ▼
Print Success Print Error
│ │
└───────┬───────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 7 Completed
Next: Part 8 — App5: Insert Multiple Rows using executemany()
Introduction
In the previous application, we inserted one record into the employees table.
In this application, we will insert multiple records into the employees table by using the executemany() method.
The executemany() method is used to execute a parameterized SQL query for multiple records at once.
This application demonstrates:
- Inserting multiple employee records
- Creating a parameterized SQL statement
- Using named bind variables
- Storing records in a list of tuples
- Using
executemany() - Using
commit() - Using
rollback()when an error occurs - Using
try-except-finally - Closing Database resources
Python Program
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Create Parameterized SQL
│
▼
Create Records List
│
▼
executemany()
│
▼
Insert Multiple Rows
│
▼
commit()
What is executemany()?
executemany() is a Cursor method used to execute the same parameterized SQL statement for multiple sets of values.
Instead of calling execute() separately for every employee, we can provide all employee records together.
General Idea
cursor.executemany(sql, records)
Here:
| Argument | Purpose |
|---|---|
sql |
Parameterized SQL statement |
records |
Collection containing multiple sets of values |
SQL Statement
+
Multiple Records
│
▼
executemany()
│
▼
Multiple Rows Inserted
App5 — Program to Insert Multiple Rows
The program inserts the following three employee records:
| Employee No | Employee Name | Salary | Address |
|---|---|---|---|
| 200 | Sunny | 2000 | Mumbai |
| 300 | Chinny | 3000 | Hyd |
| 400 | Bunny | 4000 | Hyd |
Complete Program
main.py
No output captured.
Understanding the Program
The complete application follows this sequence:
Import cx_Oracle
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Create SQL Statement
│
▼
Create Records List
│
▼
executemany(sql, records)
│
▼
Insert All Records
│
▼
commit()
│
▼
Print Success Message
│
▼
Close Resources
Step 1 — Import the Module
The program starts with:
import cx_Oracle
The cx_Oracle module is imported to communicate with Oracle Database.
Python │ ▼ cx_Oracle │ ▼ Oracle Database
Step 2 — Establish Database Connection
The program establishes a connection using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection details used in the document are:
| Detail | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The returned Connection object is stored in:
con
Connection Flow
cx_Oracle.connect(
'scott/tiger@localhost'
)
│
▼
Oracle Database
│
▼
Connection Established
│
▼
Connection Object
│
▼
con
Step 3 — Create Cursor Object
After establishing the connection, the program creates a Cursor:
cursor = con.cursor()
The Cursor object is used to execute SQL statements.
Connection
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
cursor
In this application, the Cursor will execute the parameterized INSERT statement for multiple employee records.
Step 4 — Create the SQL Statement
The program creates the following SQL statement:
sql = "insert into employees values(:eno,:ename,:esal,:eaddr)"
This is a parameterized SQL statement.
Instead of directly placing actual employee values in the SQL statement, it contains placeholders.
:eno :ename :esal :eaddr
These placeholders receive the actual values from each employee record.
Parameterized SQL Statement
The SQL statement is:
insert into employees values(:eno,:ename,:esal,:eaddr)
The placeholders correspond to the employee information:
| Placeholder | Represents |
|---|---|
:eno |
Employee Number |
:ename |
Employee Name |
:esal |
Employee Salary |
:eaddr |
Employee Address |
What are Bind Variables?
The placeholders present in the SQL statement are called bind variables.
The program uses:
:eno :ename :esal :eaddr
The actual values are supplied separately through the records collection.
Parameterized SQL
│
├── :eno
├── :ename
├── :esal
└── :eaddr
│
▼
Actual Values from Records
Why Use a Parameterized SQL Statement?
A parameterized SQL statement allows the same SQL structure to be reused for multiple records.
For example:
insert into employees values(:eno,:ename,:esal,:eaddr)
The SQL structure remains the same.
Only the employee values change:
(200, 'Sunny', 2000, 'Mumbai') (300, 'Chinny', 3000, 'Hyd') (400, 'Bunny', 4000, 'Hyd')
This makes it suitable for executemany().
Records List
The employee records are stored in a list of tuples:
records = [
(200, 'Sunny', 2000, 'Mumbai'),
(300, 'Chinny', 3000, 'Hyd'),
(400, 'Bunny', 4000, 'Hyd')
]
The variable:
records
contains all the employee records that will be inserted.
Understanding List of Tuples
The outer structure is a Python list:
[
...,
...,
...
]
Each employee record is represented using a tuple:
(200, 'Sunny', 2000, 'Mumbai')
Therefore, the complete structure is:
List │ ├── Tuple 1 │ ├── Tuple 2 │ └── Tuple 3
or:
records │ ├── (200, 'Sunny', 2000, 'Mumbai') │ ├── (300, 'Chinny', 3000, 'Hyd') │ └── (400, 'Bunny', 4000, 'Hyd')
First Employee Record
(200, 'Sunny', 2000, 'Mumbai')
| Column | Value |
|---|---|
eno |
200 |
ename |
Sunny |
esal |
2000 |
eaddr |
Mumbai |
Second Employee Record
(300, 'Chinny', 3000, 'Hyd')
| Column | Value |
|---|---|
eno |
300 |
ename |
Chinny |
esal |
3000 |
eaddr |
Hyd |
Third Employee Record
(400, 'Bunny', 4000, 'Hyd')
| Column | Value |
|---|---|
eno |
400 |
ename |
Bunny |
esal |
4000 |
eaddr |
Hyd |
How Records Match the SQL Placeholders
The SQL statement contains four placeholders:
:eno :ename :esal :eaddr
Each tuple also contains four values.
(200, 'Sunny', 2000, 'Mumbai') │ │ │ │ ▼ ▼ ▼ ▼ eno ename esal eaddr
The same mapping is used for every employee record.
Step 5 — Insert Multiple Records
The program inserts all records using:
cursor.executemany(sql, records)
The executemany() method executes the same SQL statement for every tuple present in the records list.
Instead of calling execute() multiple times, a single executemany() call processes the complete collection.
How executemany() Works
sql
│
│ insert into employees
│ values(:eno,:ename,:esal,:eaddr)
│
├──────────────────────────────┐
│ │
▼ ▼
records executemany()
│ │
├── Record 1 ──────────────────┤
├── Record 2 ──────────────────┤
└── Record 3 ──────────────────┤
│
▼
Oracle Database
│
▼
employees Table
Conceptual Execution for Each Record
Conceptually, executemany() applies the INSERT statement to every record.
Record 1
INSERT INTO employees VALUES(200,'Sunny',2000,'Mumbai');
Record 2
INSERT INTO employees VALUES(300,'Chinny',3000,'Hyd');
Record 3
INSERT INTO employees VALUES(400,'Bunny',4000,'Hyd');
In the actual Python program, however, we do not manually write these three INSERT statements. The parameterized SQL and executemany() handle the multiple value sets.
Employees Table after Insertion
After these records are inserted and committed, the employee data involved in Part 7 and Part 8 can be represented as:
+-----+--------+------+---------+ | eno | ename | esal | eaddr | +-----+--------+------+---------+ | 100 | Durga | 1000 | Hyd | | 200 | Sunny | 2000 | Mumbai | | 300 | Chinny | 3000 | Hyd | | 400 | Bunny | 4000 | Hyd | +-----+--------+------+---------+
The 100 record was inserted in the previous application, while App5 inserts the remaining three records.
Step 6 — Commit the Changes
After inserting the records, the program executes:
con.commit()
The commit() method permanently saves all inserted records in the Database.
executemany()
│
▼
Multiple Rows Inserted
│
▼
Transaction Changes
│
▼
con.commit()
│
▼
Changes Saved
Why commit() is Required
INSERT is a DML operation.
The document explains that for DML operations such as:
INSERT UPDATE DELETE
we use commit() to save the transaction changes permanently.
INSERT Multiple Rows
│
▼
Temporary Transaction Changes
│
▼
con.commit()
│
▼
Records Permanently Saved
Step 7 — Display Success Message
After committing the transaction, the program executes:
print("Records Inserted Successfully")
The output is:
Records Inserted Successfully
This message indicates that execution reached the success statement after executemany() and commit().
Exception Handling
The program handles Oracle Database errors using:
except cx_Oracle.DatabaseError as e:
If an SQL-related Database error occurs, the exception object is stored in:
e
try
│
▼
executemany()
│
▼
Error?
├── No → commit()
│
└── Yes
│
▼
cx_Oracle.DatabaseError
│
▼
e
Rollback
If an error occurs during insertion, the program executes:
if con:
con.rollback()
If the Connection object exists:
con.rollback()
cancels the uncommitted transaction changes.
Insertion Error
│
▼
DatabaseError
│
▼
if con
│
▼
rollback()
│
▼
Cancel Pending Changes
Why rollback() is Important with Multiple Inserts
Multiple employee records are being processed as part of the transaction.
If a Database error occurs before commit(), the program uses:
con.rollback()
to roll back the pending transaction changes.
Record 1 Record 2 Record 3 │ ▼ Pending Transaction │ ├── Success → commit() │ └── Error → rollback()
Display Error Message
After the rollback check, the program executes:
print("There is a problem with sql", e)
This displays the SQL error along with the exception information stored in e.
There is a problem with sql <Database Error>
Finally Block
The finally block executes whether an exception occurs or not.
Its purpose is to release Database resources.
finally:
if cursor:
cursor.close()
if con:
con.close()
try
│
┌──────┴──────┐
│ │
Success Error
│ │
│ except
│ │
└──────┬──────┘
▼
finally
│
▼
Close Resources
Close Cursor
The Cursor is closed using:
if cursor:
cursor.close()
This releases the Cursor resource after the Database operation is complete.
Close Connection
The Database Connection is closed using:
if con:
con.close()
This releases the connection to Oracle Database.
Difference Between execute() and executemany()
execute() |
executemany() |
|---|---|
| Executes one SQL statement for one record | Executes the same parameterized SQL statement for multiple records |
| Used in the previous example for inserting a single row | Used here for inserting multiple rows |
| Called separately when processing individual records | Called once for the collection of records |
The document uses executemany() together with a parameterized SQL statement and a list of tuples.
execute() Example
For a single employee:
cursor.execute(
"insert into employees values(100,'Durga',1000,'Hyd')"
)
This inserts one record.
execute() │ ▼ Single Record
executemany() Example
For multiple employees:
sql = "insert into employees values(:eno,:ename,:esal,:eaddr)"
records = [
(200, 'Sunny', 2000, 'Mumbai'),
(300, 'Chinny', 3000, 'Hyd'),
(400, 'Bunny', 4000, 'Hyd')
]
cursor.executemany(sql, records)
executemany()
│
▼
Multiple Records
execute() vs executemany() Flow
execute() │ ▼ SQL + One Record │ ▼ One Row executemany() │ ▼ Parameterized SQL + List of Records │ ▼ Multiple Rows
Complete Successful Execution Flow
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Create Parameterized SQL
│
▼
Create Records
│
▼
cursor.executemany(
sql, records
)
│
▼
Insert 3 Records
│
▼
con.commit()
│
▼
Save All Records
│
▼
"Records Inserted Successfully"
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Complete Error Execution Flow
START
│
▼
executemany()
│
▼
Database Error
│
▼
cx_Oracle.DatabaseError as e
│
▼
if con
│
▼
con.rollback()
│
▼
Cancel Pending Changes
│
▼
Print SQL Error
│
▼
finally
│
▼
cursor.close()
│
▼
con.close()
│
▼
END
Program Flow
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Create Parameterized SQL
│
▼
Create Records List
│
▼
executemany(sql, records)
│
▼
Commit Changes
│
▼
Records Inserted Successfully
│
▼
Exception?
┌──┴──┐
│ │
No Yes
│ │
▼ ▼
Close Rollback
Resources Print Error
│ │
└──┬──┘
▼
Program Ends
Line-by-Line Explanation
| Statement | Purpose |
|---|---|
import cx_Oracle |
Imports Oracle Database support |
cx_Oracle.connect(...) |
Establishes the Oracle connection |
con.cursor() |
Creates a Cursor object |
sql = "insert ..." |
Creates the parameterized INSERT statement |
records = [...] |
Stores multiple employee records |
cursor.executemany(sql, records) |
Executes the INSERT statement for all records |
con.commit() |
Permanently saves the inserted records |
print(...) |
Displays the success message |
except cx_Oracle.DatabaseError as e |
Handles Oracle Database errors |
con.rollback() |
Cancels pending changes when an error occurs |
cursor.close() |
Closes the Cursor |
con.close() |
Closes the Connection |
Methods Used
| Method | Purpose |
|---|---|
connect() |
Creates a Database connection |
cursor() |
Creates a Cursor object |
executemany() |
Executes the same parameterized SQL statement for multiple records |
commit() |
Saves all inserted records permanently |
rollback() |
Cancels pending changes if an error occurs |
close() |
Closes the Cursor and Connection |
Complete Program with Comments
main.py
No output captured.
Important Points
- The application inserts multiple rows into the
employeestable. - The method used is
executemany(). - The SQL statement is parameterized.
- The SQL statement contains the named bind variables
:eno,:ename,:esal, and:eaddr. - The employee data is stored in a list of tuples.
- Each tuple represents one employee record.
- The program inserts three employee records.
- The employees inserted are Sunny, Chinny, and Bunny.
executemany()applies the same SQL statement to all records.- We do not need to manually call
execute()once for every record. commit()saves all inserted records permanently.- If a Database error occurs before the transaction is committed,
rollback()cancels pending changes. cx_Oracle.DatabaseErroris used for Oracle Database exception handling.- The
finallyblock is used to release Database resources. - The Cursor is closed before the Connection.
Summary
| Topic | Description |
|---|---|
| Application | App5 |
| SQL Operation | Insert Multiple Rows |
| Table | employees |
| Method Used | executemany() |
| SQL Statement | insert into employees values(:eno,:ename,:esal,:eaddr) |
| Data Source | List of tuples (records) |
| Number of Records | 3 |
| Employees | Sunny, Chinny, Bunny |
| Commit Required | Yes |
| Commit Method | con.commit() |
| Error Handling | rollback() |
| Exception | cx_Oracle.DatabaseError |
| Resource Cleanup | cursor.close() and con.close() |
Quick Revision
App5 │ ▼ Insert Multiple Rows │ ▼ Create Parameterized SQL │ ├── :eno ├── :ename ├── :esal └── :eaddr │ ▼ Create records List │ ├── Sunny ├── Chinny └── Bunny │ ▼ cursor.executemany(sql, records) │ ▼ Insert 3 Records │ ▼ con.commit() │ ▼ Records Saved If Error │ ▼ DatabaseError │ ▼ con.rollback() Finally │ ▼ cursor.close() │ ▼ con.close()
Part 8 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Create Parameterized SQL
│
▼
Create List
of Tuples
│
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
Sunny Chinny Bunny
│ │ │
└────────────┼────────────┘
▼
executemany(sql, records)
│
▼
Insert 3 Records
│
┌──────┴──────┐
│ │
Success Error
│ │
▼ ▼
commit() DatabaseError
│ │
▼ ▼
Save Records rollback()
│ │
▼ ▼
Print Success Print Error
│ │
└──────┬──────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 8 Completed
Next: Part 9 — App6: Insert Multiple Rows with Dynamic Input from Keyboard
Introduction
In the previous application, we inserted multiple employee records by creating a fixed list of tuples inside the Python program.
In this application, we will make the program dynamic.
The employee information will be taken from the user through the keyboard.
The program repeatedly asks the user to enter:
- Employee Number
- Employee Name
- Employee Salary
- Employee Address
After inserting one employee record, the program asks whether the user wants to insert another record.
Start Program
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Read Employee Details
│
▼
Execute INSERT
│
▼
Ask "Do you want to insert one more record?"
│
┌─┴─┐
│ │
Yes No
│ │
│ ▼
│ commit()
│ │
│ ▼
│ End
│
└──► Read Next Employee
Static Input vs Dynamic Input
In App5, employee records were written directly inside the program:
records = [
(200, 'Sunny', 2000, 'Mumbai'),
(300, 'Chinny', 3000, 'Hyd'),
(400, 'Bunny', 4000, 'Hyd')
]
This is fixed data.
In App6, employee information is entered at runtime:
eno = int(input("Enter Employee Number:"))
ename = input("Enter Employee Name:")
esal = float(input("Enter Employee Salary:"))
eaddr = input("Enter Employee Address:")
| App5 | App6 |
|---|---|
| Records are predefined | Records are entered by the user |
| Static data | Dynamic data |
| Uses a list of tuples | Uses keyboard input |
Uses executemany() |
Uses execute() repeatedly |
App6 — Complete Program
main.py
No output captured.
Main Idea of the Program
The main purpose of App6 is to insert an unknown number of employee records.
We do not know beforehand how many employees the user wants to enter.
Therefore, the program uses:
while True:
After every insertion, it asks:
Do you want to insert one more record [Yes|No]:
If the answer is:
Yes
the loop continues.
If the answer is:
No
the program executes:
break
and terminates the loop.
Step 1 — Import cx_Oracle
The program starts with:
import cx_Oracle
The cx_Oracle module provides the required functionality to communicate with Oracle Database.
Python │ ▼ cx_Oracle │ ▼ Oracle Database
Step 2 — Establish Database Connection
The connection is established using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection details used in the tutorial are:
| Property | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database / Host | localhost |
The returned Connection object is stored in:
con
Step 3 — Create Cursor Object
The Cursor object is created using:
cursor = con.cursor()
The Cursor is required to execute the INSERT SQL statements.
Connection Object
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
cursor
Step 4 — Start Infinite Loop
The program uses:
while True:
Since the condition is always True, this creates an infinite loop.
The loop continues until the program explicitly executes:
break
while True
│
▼
Read Employee
│
▼
Insert Record
│
▼
Insert Another?
│
┌──┴──┐
│ │
Yes No
│ │
│ ▼
│ break
│
└────► Repeat
Why while True is Used
The number of employee records is not fixed.
For example, one user may want to insert:
2 employees
while another user may want to insert:
10 employees
Therefore, instead of fixing the number of iterations, the program continues until the user chooses to stop.
Unknown Number of Records
│
▼
while True
│
▼
Continue Until User Says No
Step 5 — Read Employee Number
The employee number is read using:
eno = int(input("Enter Employee Number:"))
input() returns keyboard input as a string.
Because employee number should be numeric, the program converts it using:
int()
Example:
Enter Employee Number:500
Now:
eno = 500
Step 6 — Read Employee Name
The employee name is read using:
ename = input("Enter Employee Name:")
No explicit type conversion is required because input() already returns a string.
Example:
Enter Employee Name:Sachin
Now:
ename = "Sachin"
Step 7 — Read Employee Salary
The salary is read using:
esal = float(input("Enter Employee Salary:"))
The keyboard value is converted into a floating-point number using:
float()
Example:
Enter Employee Salary:5000
Internally:
esal = 5000.0
Step 8 — Read Employee Address
The employee address is read using:
eaddr = input("Enter Employee Address:")
Example:
Enter Employee Address:Mumbai
The value is stored in:
eaddr = "Mumbai"
Employee Input Summary
Suppose the user enters:
Enter Employee Number:500 Enter Employee Name:Sachin Enter Employee Salary:5000 Enter Employee Address:Mumbai
The Python variables contain:
| Variable | Value | Type |
|---|---|---|
eno |
500 | int |
ename |
Sachin | str |
esal |
5000.0 | float |
eaddr |
Mumbai | str |
Step 9 — Create SQL Query
The tutorial creates the INSERT query as:
sql = "insert into employees values(%d,'%s',%f,'%s')"
The query contains format specifiers:
| Specifier | Used For |
|---|---|
%d |
Employee Number |
%s |
Employee Name |
%f |
Employee Salary |
%s |
Employee Address |
Understanding the SQL String
sql = "insert into employees values(%d,'%s',%f,'%s')"
The mapping is:
%d → eno '%s' → ename %f → esal '%s' → eaddr
Notice that string values are placed inside single quotes:
'%s'
because SQL string values require quotes.
Step 10 — Substitute Values into SQL
The program executes:
cursor.execute(sql % (eno, ename, esal, eaddr))
The expression:
sql % (eno, ename, esal, eaddr)
substitutes the current employee values into the SQL string.
For example:
eno = 500 ename = "Sachin" esal = 5000.0 eaddr = "Mumbai"
The generated SQL becomes conceptually:
insert into employees values(500,'Sachin',5000.000000,'Mumbai')
Step 11 — Execute INSERT Statement
The SQL statement is executed using:
cursor.execute(sql % (eno, ename, esal, eaddr))
The execution flow is:
Keyboard Input
│
▼
Python Variables
│
▼
Format SQL String
│
▼
cursor.execute()
│
▼
Oracle Database
│
▼
employees Table
│
▼
New Record
Important Modern Practice — Use Bind Variables
The program above follows the tutorial's original % string-formatting example.
For real applications, values should normally be passed using bind variables instead of constructing SQL by directly inserting user input into the SQL string.
A safer form is:
sql = """
insert into employees
values(:eno, :ename, :esal, :eaddr)
"""
cursor.execute(
sql,
eno=eno,
ename=ename,
esal=esal,
eaddr=eaddr
)
This keeps SQL code and user-provided values separate.
| Approach | Recommendation |
|---|---|
sql % (...) |
Shown to explain the original tutorial example |
| Bind variables | Preferred for real Database applications |
Step 12 — Print Success Message
After executing the INSERT statement, the program displays:
print("Record Inserted Successfully")
Output:
Record Inserted Successfully
This message is displayed for every successfully executed INSERT statement.
Step 13 — Ask Whether to Insert Another Record
The program asks:
option = input("Do you want to insert one more record [Yes|No]:")
The user's answer is stored in:
option
For example:
Do you want to insert one more record [Yes|No]:Yes
or:
Do you want to insert one more record [Yes|No]:No
Step 14 — Check option
The program checks:
if option == "No":
break
If the user enters exactly:
No
the break statement terminates the while loop.
Otherwise, the loop continues and the program asks for another employee record.
Understanding break
break immediately terminates the nearest loop.
if option == "No":
break
Execution:
option
│
▼
Is option == "No"?
/ \
Yes No
│ │
▼ ▼
break Continue
│ │
▼ │
Exit Loop │
└──► Next Employee
What Happens When User Enters Yes?
Suppose the user enters:
Yes
The condition:
option == "No"
becomes:
False
Therefore, break is not executed.
The while True loop starts its next iteration.
Yes │ ▼ Condition False │ ▼ No break │ ▼ Repeat Loop │ ▼ Enter Next Employee
What Happens When User Enters No?
Suppose the user enters:
No
The condition:
option == "No"
becomes:
True
Therefore:
break
is executed and the loop terminates.
No │ ▼ Condition True │ ▼ break │ ▼ Exit while Loop │ ▼ con.commit()
Step 15 — commit()
After the user finishes inserting records, the program executes:
con.commit()
The INSERT operations are DML operations.
commit() permanently saves the inserted employee records.
Employee 1 INSERT
Employee 2 INSERT
Employee 3 INSERT
│
▼
Pending Transaction
│
▼
con.commit()
│
▼
All Changes Saved
Why commit() is Outside the Loop
In this program, commit() is placed after the while loop.
while True:
...
cursor.execute(...)
...
con.commit()
This means the program can execute multiple INSERT operations first.
After the user finishes entering records, the transaction is committed.
Insert Record 1
│
Insert Record 2
│
Insert Record 3
│
User Enters No
│
▼
Exit Loop
│
▼
commit()
│
▼
Save Transaction
Sample Execution — Insert One Record
Suppose the user enters only one employee:
Enter Employee Number:500 Enter Employee Name:Sachin Enter Employee Salary:5000 Enter Employee Address:Mumbai Record Inserted Successfully Do you want to insert one more record [Yes|No]:No
The user enters No, so the loop terminates and the transaction is committed.
Sample Execution — Insert Multiple Records
Suppose the user wants to insert three records:
Enter Employee Number:500 Enter Employee Name:Sachin Enter Employee Salary:5000 Enter Employee Address:Mumbai Record Inserted Successfully Do you want to insert one more record [Yes|No]:Yes Enter Employee Number:600 Enter Employee Name:Dhoni Enter Employee Salary:6000 Enter Employee Address:Ranchi Record Inserted Successfully Do you want to insert one more record [Yes|No]:Yes Enter Employee Number:700 Enter Employee Name:Kohli Enter Employee Salary:7000 Enter Employee Address:Delhi Record Inserted Successfully Do you want to insert one more record [Yes|No]:No
After No is entered, the loop terminates and commit() saves the transaction.
Dynamic Insertion Flow
while True
│
▼
Read Employee
│
▼
Execute INSERT
│
▼
Print Success Message
│
▼
Ask Yes / No
│
┌──────┴──────┐
│ │
Yes No
│ │
▼ ▼
Next Iteration break
│
▼
commit()
Exception Handling
The program handles Oracle Database errors using:
except cx_Oracle.DatabaseError as e:
If an Oracle Database error occurs, the exception object is stored in:
e
Database Operation
│
▼
DatabaseError?
┌───┴───┐
│ │
No Yes
│ │
▼ ▼
Continue except
│
▼
e
rollback()
If a Database error occurs, the program checks:
if con:
con.rollback()
If the Connection object exists:
con.rollback()
cancels the pending transaction changes.
Multiple INSERT Operations
│
▼
Pending Transaction
│
▼
Database Error
│
▼
rollback()
│
▼
Cancel Pending Changes
Important Transaction Behaviour
Because commit() is executed only after the loop finishes, the inserted records belong to the current transaction until that commit occurs.
Consider:
Record 1 → INSERT successful Record 2 → INSERT successful Record 3 → DatabaseError
If the transaction has not yet been committed, the exception handler calls:
con.rollback()
This rolls back the pending changes in that transaction.
Record 1 ─┐
Record 2 ─┼──► Pending Transaction
Record 3 ─┘ │
▼
Error
│
▼
rollback()
Display Database Error
The program displays the Database error using:
print("There is a problem with sql", e)
The general output structure is:
There is a problem with sql <Oracle Database Error>
finally Block
The finally block is:
finally:
if cursor:
cursor.close()
if con:
con.close()
It executes whether the program completes successfully or a Database exception occurs.
Its main purpose is resource cleanup.
Close Cursor
The Cursor is closed using:
if cursor:
cursor.close()
If the Cursor object exists, close() releases the Cursor resource.
Close Connection
The Connection is closed using:
if con:
con.close()
This releases the Oracle Database connection.
Complete Successful Execution Flow
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
while True
│
▼
Read eno, ename,
esal, eaddr
│
▼
Create SQL Query
│
▼
cursor.execute()
│
▼
Record Inserted
│
▼
Ask Yes or No
│
┌────────┴────────┐
│ │
Yes No
│ │
▼ ▼
Repeat Loop break
│
▼
con.commit()
│
▼
Save All Records
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Complete Error Execution Flow
START
│
▼
Database Operation
│
▼
DatabaseError
│
▼
except cx_Oracle.DatabaseError as e
│
▼
if con
│
▼
con.rollback()
│
▼
Cancel Pending Changes
│
▼
Print SQL Error
│
▼
finally
│
▼
cursor.close()
│
▼
con.close()
│
▼
END
App5 vs App6
| Feature | App5 | App6 |
|---|---|---|
| Input | Fixed records | Keyboard input |
| Records | Known beforehand | Entered dynamically |
| Main Method | executemany() |
execute() |
| Loop | Not required for input | while True |
| Stopping Condition | List finishes | User enters No |
| Transaction | commit() |
commit() |
| Error Handling | rollback() |
rollback() |
Methods and Functions Used
| Method / Function | Purpose |
|---|---|
cx_Oracle.connect() |
Establishes Oracle Database connection |
con.cursor() |
Creates Cursor object |
input() |
Reads data from keyboard |
int() |
Converts employee number to integer |
float() |
Converts salary to floating-point value |
cursor.execute() |
Executes the INSERT query |
con.commit() |
Permanently saves inserted records |
con.rollback() |
Cancels pending transaction changes |
cursor.close() |
Closes Cursor |
con.close() |
Closes Connection |
Important Statements Used
| Statement | Purpose |
|---|---|
while True |
Repeats employee insertion |
if option == "No" |
Checks whether the user wants to stop |
break |
Terminates the loop |
try |
Contains Database operations |
except |
Handles Database errors |
finally |
Performs resource cleanup |
Complete Program with Comments
main.py
No output captured.
Safer Version using Bind Variables
main.py
No output captured.
Important Points
- App6 inserts multiple employee records dynamically.
- Employee information is accepted from the keyboard using
input(). int()converts employee number into an integer.float()converts employee salary into a floating-point value.- The program uses
while Truebecause the number of employee records is not fixed. - The loop continues until the user enters
No. breakterminates the loop.- The original tutorial constructs the INSERT statement using
%d,%s, and%fformat specifiers. cursor.execute()executes one INSERT statement during each loop iteration.- After every successful INSERT, the program asks whether another employee should be inserted.
commit()is placed after the loop and saves the transaction.- If a Database error occurs before commit,
rollback()cancels pending transaction changes. cx_Oracle.DatabaseErrorhandles Oracle Database-related errors.- The
finallyblock closes the Cursor and Connection. - For modern real-world code, bind variables should be preferred over constructing SQL directly from keyboard input.
Summary
| Topic | Description |
|---|---|
| Application | App6 |
| Purpose | Insert multiple records dynamically |
| Input | Keyboard |
| Input Function | input() |
| Loop | while True |
| Stop Statement | break |
| SQL Operation | INSERT |
| Execution Method | execute() |
| Save Transaction | commit() |
| Cancel Transaction | rollback() |
| Exception | cx_Oracle.DatabaseError |
| Cleanup | finally |
Quick Revision
App6
│
▼
Dynamic Multiple INSERT
│
▼
while True
│
▼
Read eno
Read ename
Read esal
Read eaddr
│
▼
Create INSERT SQL
│
▼
cursor.execute()
│
▼
Record Inserted
│
▼
Ask Yes / No
│
├── Yes → Repeat
│
└── No
│
▼
break
│
▼
con.commit()
│
▼
Records Saved
If Error
│
▼
DatabaseError
│
▼
rollback()
Finally
│
▼
Close Cursor
│
▼
Close Connection
Part 9 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
while True
│
▼
Take Employee Details
from Keyboard
│
▼
Execute INSERT
│
▼
Record Inserted
│
▼
Ask Another Record?
/ \
Yes No
│ │
│ ▼
│ break
│ │
└── Repeat ▼
commit()
│
┌─────┴─────┐
│ │
Success Error
│ │
│ ▼
│ DatabaseError
│ │
│ ▼
│ rollback()
│ │
└─────┬─────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 9 Completed
Next: Part 10 — App7: Update Employee Record
Introduction
In this application, we will learn how to update employee salaries in the employees table.
The salary increment and salary range are taken dynamically from the keyboard.
The program updates only those employees whose salary is less than the salary range entered by the user.
Example given in the tutorial:
Increment all employee salaries by 500 whose salary is less than 5000.
This application demonstrates:
- Using the SQL
UPDATEstatement - Taking salary increment dynamically
- Taking salary range dynamically
- Updating multiple employee records
- Using
execute() - Using
commit() - Using
rollback() - Handling Database errors
- Closing Database resources
Keyboard Input
│
├── Increment Salary
│
└── Salary Range
│
▼
UPDATE employees
│
▼
Increase Salaries
│
▼
commit()
What is UPDATE?
UPDATE is a DML statement used to modify existing records in a Database table.
General Syntax
UPDATE table_name SET column_name = new_value WHERE condition;
For this application:
UPDATE employees SET esal = esal + increment WHERE esal < salary_range;
The existing salary is increased instead of replacing it with a completely unrelated fixed value.
UPDATE is a DML Operation
UPDATE belongs to DML — Data Manipulation Language.
| DML Statement | Purpose |
|---|---|
INSERT |
Add new records |
UPDATE |
Modify existing records |
DELETE |
Remove existing records |
Because UPDATE modifies data, the program uses:
con.commit()
to permanently save the changes.
App7 — Program to Update Employee Salaries
The program accepts two values from the keyboard:
| Input | Purpose |
|---|---|
| Increment Salary | Amount to add to the existing salary |
| Salary Range | Maximum salary limit used for selecting employees |
For example:
Increment Salary = 500 Salary Range = 5000
The program increases salaries by 500 for employees whose current salary is less than 5000.
Complete Program
main.py
No output captured.
Understanding the Program
The complete program performs the following operations:
Import cx_Oracle
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Read Increment Salary
│
▼
Read Salary Range
│
▼
Create UPDATE SQL
│
▼
Execute UPDATE Query
│
▼
Display Success Message
│
▼
commit()
│
▼
Close Resources
Step 1 — Import the Module
The program starts with:
import cx_Oracle
The cx_Oracle module is imported to communicate with Oracle Database.
Python Program
│
▼
cx_Oracle
│
▼
Oracle Database
Step 2 — Establish Database Connection
The connection is established using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection details used in the tutorial are:
| Property | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The returned Connection object is stored in:
con
Step 3 — Create Cursor Object
The Cursor object is created using:
cursor = con.cursor()
The Cursor is required to execute the UPDATE SQL statement.
Connection
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
cursor
Step 4 — Read Dynamic Input
The program reads two values dynamically from the keyboard.
increment = float(input("Enter Increment Salary:"))
salrange = float(input("Enter Salary Range:"))
| Variable | Description |
|---|---|
increment |
Salary amount to be added |
salrange |
Maximum salary limit for updating employees |
Read Increment Salary
The salary increment is read using:
increment = float(input("Enter Increment Salary:"))
Example:
Enter Increment Salary:500
The entered value is converted into a floating-point number:
increment = 500.0
This value will be added to the existing employee salary.
Read Salary Range
The salary range is read using:
salrange = float(input("Enter Salary Range:"))
Example:
Enter Salary Range:5000
The value becomes:
salrange = 5000.0
Only employees whose salary is less than this value will be updated.
Dynamic Input Example
Suppose the user enters:
Enter Increment Salary:500 Enter Salary Range:5000
The variables contain:
| Variable | Value |
|---|---|
increment |
500.0 |
salrange |
5000.0 |
The meaning is:
Add 500 to salary ONLY IF current salary < 5000
Step 5 — Create UPDATE SQL Statement
The SQL statement is created as:
sql = "update employees set esal=esal+%f where esal<%f"
This statement updates salaries for employees whose current salary is less than the specified salary range.
The SQL contains two %f format specifiers.
| Specifier | Represents |
|---|---|
First %f |
Salary increment |
Second %f |
Salary range |
Understanding the UPDATE Query
update employees set esal = esal + %f where esal < %f
The query contains three important parts:
| SQL Part | Meaning |
|---|---|
update employees |
Selects the employees table for updating |
set esal=esal+%f |
Adds the increment to the current salary |
where esal<%f |
Updates only employees below the salary range |
Understanding SET Clause
The SET clause is:
set esal = esal + %f
It does not simply replace the salary with the increment value.
Instead:
New Salary = Existing Salary + Increment
For example:
Existing Salary = 3000
Increment = 500
New Salary = 3000 + 500
= 3500
Understanding WHERE Clause
The WHERE clause is:
where esal < %f
It determines which employee records should be updated.
If:
salrange = 5000
then:
WHERE esal < 5000
Only employees with a salary below 5000 are selected for the update.
Why WHERE Clause is Important
The WHERE clause restricts the UPDATE operation to matching records.
UPDATE employees SET esal = esal + 500 WHERE esal < 5000
Employees satisfying:
esal < 5000
are updated.
Employees that do not satisfy the condition are not updated.
Employee Salary
│
▼
Is Salary < 5000?
/ \
Yes No
│ │
▼ ▼
Update No Update
Salary
SQL Statement Example
The example given in the tutorial is:
Increment Salary → 500 Salary Range → 5000
After substituting these values, the SQL statement becomes:
UPDATE employees SET esal = esal + 500 WHERE esal < 5000;
This means:
Find every employee
whose salary is below 5000
│
▼
Add 500 to that employee's salary
Example — Before Updating Salaries
Suppose the employees table contains:
+-----+--------+------+ | eno | ename | esal | +-----+--------+------+ | 100 | Durga | 1000 | | 200 | Sunny | 2000 | | 300 | Chinny | 3000 | | 400 | Bunny | 4000 | | 500 | Sachin | 5000 | | 600 | Dhoni | 6000 | +-----+--------+------+
Suppose the user enters:
Increment Salary = 500 Salary Range = 5000
The condition is:
esal < 5000
Example — Which Employees are Updated?
| Employee | Current Salary | Salary < 5000? | Updated? |
|---|---|---|---|
| Durga | 1000 | Yes | Yes |
| Sunny | 2000 | Yes | Yes |
| Chinny | 3000 | Yes | Yes |
| Bunny | 4000 | Yes | Yes |
| Sachin | 5000 | No | No |
| Dhoni | 6000 | No | No |
Notice that a salary equal to 5000 is not updated because the condition uses:
<
not:
<=
Example — Salary Calculation
The qualifying salaries are increased by 500.
1000 + 500 = 1500 2000 + 500 = 2500 3000 + 500 = 3500 4000 + 500 = 4500
The other salaries remain unchanged:
5000 → 5000 6000 → 6000
Example — After Updating Salaries
+-----+--------+------+ | eno | ename | esal | +-----+--------+------+ | 100 | Durga | 1500 | | 200 | Sunny | 2500 | | 300 | Chinny | 3500 | | 400 | Bunny | 4500 | | 500 | Sachin | 5000 | | 600 | Dhoni | 6000 | +-----+--------+------+
Only employees satisfying the WHERE condition have their salary increased.
Step 6 — Execute UPDATE Query
The UPDATE query is executed using:
cursor.execute(sql % (increment, salrange))
The values entered by the user are substituted into the SQL statement.
For example:
increment = 500 salrange = 5000
results in:
update employees set esal=esal+500 where esal<5000
How execute() Works
increment
│
├───────────┐
│ │
salrange │
│ │
└─────┬─────┘
▼
Format SQL Query
│
▼
cursor.execute()
│
▼
Oracle Database
│
▼
employees Table
│
▼
Find Matching Records
│
▼
Update Salaries
Step 7 — Display Success Message
After the UPDATE query executes successfully, the program displays:
print("Records Updated Successfully")
Output:
Records Updated Successfully
The word Records is used because the UPDATE statement may modify multiple employee rows.
Step 8 — Commit the Changes
After the successful UPDATE operation, the program executes:
con.commit()
The commit() method permanently saves the updated salary values in the Database.
UPDATE Query
│
▼
Salary Values Changed
│
▼
Pending Transaction
│
▼
con.commit()
│
▼
Changes Permanently Saved
Why commit() is Required
UPDATE is a DML operation.
The transaction should be committed to permanently save the updated values.
UPDATE │ ▼ Modify Records │ ▼ commit() │ ▼ Save Changes
The same transaction concept applies to:
INSERT UPDATE DELETE
Exception Handling
The program handles Oracle Database errors using:
except cx_Oracle.DatabaseError as e:
If a Database-related error occurs, execution moves to the except block.
The exception object is stored in:
e
UPDATE Operation
│
▼
Database Error?
┌──┴──┐
│ │
No Yes
│ │
▼ ▼
commit except
│
▼
e
Rollback
If an SQL error occurs, the program executes:
if con:
con.rollback()
If the Connection object exists, rollback() cancels temporary uncommitted changes.
UPDATE │ ▼ Temporary Changes │ ▼ Error Occurs │ ▼ rollback() │ ▼ Cancel Changes
commit() vs rollback()
commit() |
rollback() |
|---|---|
| Saves changes permanently | Cancels uncommitted changes |
| Used after successful UPDATE | Used when an error occurs |
con.commit() |
con.rollback() |
UPDATE
│
▼
Transaction
/ \
/ \
▼ ▼
Success Error
│ │
▼ ▼
commit() rollback()
│ │
▼ ▼
Save Cancel
Display Error Message
The program displays the SQL error using:
print("There is a problem with sql :", e)
The general output is:
There is a problem with sql : <Oracle Database Error>
The actual exception information is stored in e.
Finally Block
The finally block executes whether an exception occurs or not.
finally:
if cursor:
cursor.close()
if con:
con.close()
Its purpose is to release Database resources.
try
│
┌─────┴─────┐
│ │
Success Error
│ │
│ except
│ │
└─────┬─────┘
▼
finally
│
▼
Close Resources
Close Cursor
The Cursor is closed using:
if cursor:
cursor.close()
This releases the Cursor resource.
Close Connection
The Connection is closed using:
if con:
con.close()
This releases the connection with Oracle Database.
Complete Program Flow
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Read Increment Salary
│
▼
Read Salary Range
│
▼
Create UPDATE SQL
│
▼
Execute UPDATE Query
│
▼
Records Updated Successfully
│
▼
Commit Changes
│
▼
Exception?
┌──┴──┐
│ │
No Yes
│ │
▼ ▼
Close Rollback
Resources Print Error
│ │
└──┬──┘
▼
Program Ends
Successful Execution Flow
START
│
▼
import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Enter Increment Salary
│
▼
Enter Salary Range
│
▼
Create UPDATE SQL
│
▼
cursor.execute()
│
▼
Find Matching Employees
│
▼
Increase Salaries
│
▼
"Records Updated Successfully"
│
▼
con.commit()
│
▼
Save Changes
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Error Execution Flow
START
│
▼
Execute UPDATE
│
▼
DatabaseError
│
▼
except cx_Oracle.DatabaseError as e
│
▼
if con
│
▼
con.rollback()
│
▼
Cancel Temporary Changes
│
▼
Print SQL Error
│
▼
finally
│
▼
cursor.close()
│
▼
con.close()
│
▼
END
Methods Used
| Method | Purpose |
|---|---|
connect() |
Creates a Database connection |
cursor() |
Creates a Cursor object |
execute() |
Executes the UPDATE SQL statement |
commit() |
Permanently saves updated records |
rollback() |
Cancels temporary changes if an error occurs |
close() |
Closes the Cursor and Connection |
Complete Program with Comments
main.py
No output captured.
Safer Version using Bind Variables
main.py
No output captured.
Why Bind Variables are Better
The original tutorial uses:
sql = "update employees set esal=esal+%f where esal<%f" cursor.execute(sql % (increment, salrange))
This is useful for understanding the original example.
For real applications, parameterized queries using bind variables are preferred:
sql = """ update employees set esal = esal + :increment where esal < :salrange """
Then the values are passed separately to execute().
This avoids manually constructing the SQL statement from input values.
Important Points
- App7 updates employee salaries in the
employeestable. - The SQL statement used is
UPDATE. UPDATEis a DML operation.- The increment amount is entered dynamically from the keyboard.
- The salary range is also entered dynamically.
- The variable
incrementstores the amount added to employee salary. - The variable
salrangestores the salary limit. - Only employees whose salary is less than the specified salary range are updated.
- The original SQL statement contains two
%fformat specifiers. - The first
%frepresents the increment amount. - The second
%frepresents the salary range. esal=esal+incrementincreases the existing salary.- The
WHEREclause controls which records are updated. execute()executes the UPDATE statement.commit()permanently saves the updated salary values.rollback()cancels uncommitted changes if an error occurs.- The program uses
try-except-finallyfor safe Database programming. - The Cursor and Connection are closed inside the
finallyblock.
Summary
| Topic | Description |
|---|---|
| Application | App7 |
| SQL Operation | Update |
| Table | employees |
| Column Updated | esal |
| SQL Statement | update employees set esal=esal+%f where esal<%f |
| Dynamic Inputs | Increment Salary, Salary Range |
| Execution Method | execute() |
| Commit Required | Yes |
| Commit Method | con.commit() |
| Error Handling | rollback() |
| Exception | cx_Oracle.DatabaseError |
| Resource Cleanup | cursor.close() and con.close() |
Quick Revision
App7 │ ▼ UPDATE Employee Salary │ ▼ Read Increment Salary │ ▼ Read Salary Range │ ▼ UPDATE employees SET esal = esal + increment WHERE esal < salary range │ ▼ cursor.execute() │ ▼ Matching Salaries Updated │ ▼ con.commit() │ ▼ Changes Saved If Error │ ▼ DatabaseError │ ▼ rollback() │ ▼ Cancel Changes Finally │ ▼ cursor.close() │ ▼ con.close()
Part 10 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Read Increment Salary
│
▼
Read Salary Range
│
▼
Create UPDATE Query
│
▼
cursor.execute()
│
▼
Check WHERE Condition
│
┌──────────┴──────────┐
│ │
Salary < Range Salary >= Range
│ │
▼ ▼
Increase Salary No Update
│
└──────────┬──────────┘
▼
Records Updated Successfully
│
▼
commit()
│
▼
Save Changes
│
┌──────┴──────┐
│ │
Success Error
│ │
│ ▼
│ DatabaseError
│ │
│ ▼
│ rollback()
│ │
└──────┬──────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 10 Completed
Next: Part 11 — App8: Delete Employees Whose Salary is Greater Than the Given Cutoff Salary
Introduction
In this application, we will learn how to delete employee records from the employees table.
The cutoff salary is taken dynamically from the keyboard.
The program deletes all employees whose salary is greater than the cutoff salary entered by the user.
Example given in the tutorial:
Delete all employees whose salary > 5000.
This application demonstrates:
- Using the SQL
DELETEstatement - Taking cutoff salary dynamically from the keyboard
- Using a
WHEREcondition - Deleting multiple matching records
- Using
execute() - Using
commit() - Using
rollback() - Handling Oracle Database errors
- Closing Database resources
Keyboard Input
│
▼
Cutoff Salary
│
▼
DELETE FROM employees
WHERE esal > cutoff
│
▼
Delete Matching Records
│
▼
commit()
What is DELETE?
The SQL DELETE statement is used to remove existing records from a Database table.
General Syntax
DELETE FROM table_name WHERE condition;
For this application:
DELETE FROM employees WHERE esal > cutoff_salary;
The WHERE condition decides which employee records should be deleted.
DELETE is a DML Operation
DELETE belongs to DML — Data Manipulation Language.
| DML Statement | Purpose |
|---|---|
INSERT |
Adds new records |
UPDATE |
Modifies existing records |
DELETE |
Removes existing records |
Because DELETE modifies table data, the program uses:
con.commit()
to permanently save the deletion.
App8 — Program to Delete Employees Using Dynamic Input
The program accepts the cutoff salary from the keyboard.
For example:
Enter CutOff Salary:5000
The program then deletes all employees satisfying:
esal > 5000
Therefore:
Salary <= 5000 → Keep Employee Salary > 5000 → Delete Employee
Complete Program
main.py
No output captured.
Understanding the Program
The program performs the following major operations:
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Read CutOff Salary
│
▼
Create DELETE SQL
│
▼
Execute DELETE Query
│
▼
Records Deleted Successfully
│
▼
Commit Changes
│
▼
Close Resources
Step 1 — Import the Module
The program starts with:
import cx_Oracle
The cx_Oracle module is imported to communicate with Oracle Database.
Python Program
│
▼
cx_Oracle
│
▼
Oracle Database
Step 2 — Establish Database Connection
A connection is established with Oracle Database using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection details used in the tutorial are:
| Property | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The returned Connection object is stored in:
con
Step 3 — Create Cursor Object
The Cursor object is created using:
cursor = con.cursor()
The Cursor object is required to execute SQL statements.
Connection Object
│
▼
con.cursor()
│
▼
Cursor Object
│
▼
cursor
In this application, the Cursor executes the DELETE query.
Step 4 — Read Cutoff Salary
The cutoff salary is read dynamically from the keyboard:
cutoffsalary = float(input("Enter CutOff Salary:"))
The entered value determines which employee records will be deleted.
Example:
Enter CutOff Salary:5000
The value returned by input() is converted into a floating-point number:
cutoffsalary = 5000.0
Understanding cutoffsalary
The variable:
cutoffsalary
stores the maximum salary limit used for deciding which employee records should be deleted.
For example:
cutoffsalary = 5000
The program checks:
Employee Salary > 5000 ?
If the condition is true, that employee record is deleted.
Employee Salary
│
▼
Salary > Cutoff?
/ \
Yes No
│ │
▼ ▼
Delete Keep
Record Record
Why float() is Used
Python's input() function returns keyboard input as a string.
Therefore:
float(input("Enter CutOff Salary:"))
converts the entered salary into a floating-point value.
Example:
Input: 5000 After float(): 5000.0
Step 5 — Create DELETE SQL Statement
The DELETE query is created using:
sql = "delete from employees where esal>%f"
This SQL statement deletes all employees whose salary is greater than the entered cutoff salary.
The %f placeholder represents:
cutoffsalary
| SQL Part | Meaning |
|---|---|
delete from employees |
Delete records from the employees table |
where |
Apply a condition |
esal |
Employee salary column |
> |
Greater-than operator |
%f |
Cutoff salary value |
Understanding the DELETE Query
delete from employees where esal>%f
The query can be understood in three parts:
delete from employees
│
▼
Select employees table
where
│
▼
Apply condition
esal > cutoffsalary
│
▼
Delete only matching employees
Understanding the WHERE Clause
The most important part of this DELETE statement is:
where esal > %f
This condition prevents every employee record from being deleted.
Suppose:
cutoffsalary = 5000
The condition becomes:
where esal > 5000
Only employees earning more than 5000 are deleted.
Why WHERE Clause is Very Important with DELETE
A DELETE statement without a WHERE condition can delete all rows from a table.
For example:
DELETE FROM employees;
This targets every employee record.
But App8 uses:
DELETE FROM employees WHERE esal > cutoffsalary;
Therefore, only matching employee records are targeted.
DELETE │ ├── Without WHERE → All rows │ └── With WHERE → Matching rows only
SQL Statement Example
The example given in the tutorial uses:
5000
as the cutoff salary.
The original SQL template is:
delete from employees where esal>%f
After substituting 5000, the SQL statement becomes:
DELETE FROM employees WHERE esal > 5000;
This matches the example provided in the tutorial.
Example — Employees Before DELETE
Suppose the employees table contains:
+-----+--------+------+ | eno | ename | esal | +-----+--------+------+ | 100 | Sachin | 3000 | | 200 | Dhoni | 4500 | | 300 | Kohli | 5000 | | 400 | Rohit | 5500 | | 500 | Rahul | 7000 | +-----+--------+------+
Now the user enters:
Enter CutOff Salary:5000
The condition becomes:
esal > 5000
Example — Which Employees are Deleted?
| Employee | Salary | Salary > 5000? | Result |
|---|---|---|---|
| Sachin | 3000 | No | Kept |
| Dhoni | 4500 | No | Kept |
| Kohli | 5000 | No | Kept |
| Rohit | 5500 | Yes | Deleted |
| Rahul | 7000 | Yes | Deleted |
Important — What Happens to Salary Equal to Cutoff?
The condition used by the program is:
esal > cutoffsalary
Therefore, if:
Salary = 5000 Cutoff Salary = 5000
then:
5000 > 5000
is False.
So an employee earning exactly the cutoff salary is not deleted.
Salary < Cutoff → Keep Salary = Cutoff → Keep Salary > Cutoff → Delete
Example — Employees After DELETE
After executing:
DELETE FROM employees WHERE esal > 5000;
the remaining records are:
+-----+--------+------+ | eno | ename | esal | +-----+--------+------+ | 100 | Sachin | 3000 | | 200 | Dhoni | 4500 | | 300 | Kohli | 5000 | +-----+--------+------+
The employees with salaries 5500 and 7000 were deleted because both values are greater than 5000.
Step 6 — Execute DELETE Query
The DELETE statement is executed using:
cursor.execute(sql % (cutoffsalary))
The value entered by the user is substituted for %f.
For example:
cutoffsalary = 5000
produces:
delete from employees where esal>5000
The Cursor sends this SQL statement to Oracle Database.
How execute() Works
cutoffsalary
│
▼
Replace %f
│
▼
DELETE SQL Statement
│
▼
cursor.execute()
│
▼
Oracle Database
│
▼
employees Table
│
▼
Check esal > cutoff
│
▼
Delete Matching Rows
Step 7 — Display Success Message
If the DELETE operation executes successfully, the program displays:
print("Records Deleted Successfully")
Output:
Records Deleted Successfully
The DELETE statement can affect multiple employees because every row satisfying the condition is deleted.
Step 8 — Commit the Changes
After deleting the matching records, the program executes:
con.commit()
The commit() method permanently saves the deletion in the Database.
DELETE Query
│
▼
Rows Deleted
│
▼
Pending Transaction
│
▼
con.commit()
│
▼
Deletion Saved Permanently
Why commit() is Required
DELETE is a DML operation.
Therefore, the transaction should be committed to permanently save the changes.
DELETE │ ▼ Remove Matching Rows │ ▼ commit() │ ▼ Save Changes Permanently
The same transaction concept applies to:
INSERT UPDATE DELETE
Sample Program Execution
Suppose the user enters:
Enter CutOff Salary:5000 Records Deleted Successfully
The program performs:
cutoffsalary = 5000.0
│
▼
DELETE FROM employees
WHERE esal > 5000
│
▼
Delete Matching Employees
│
▼
commit()
Exception Handling
The program handles Oracle Database errors using:
except cx_Oracle.DatabaseError as e:
If an Oracle Database error occurs, execution moves to the except block.
The exception object is stored in:
e
DELETE Operation
│
▼
Database Error?
/ \
No Yes
│ │
▼ ▼
Continue except
│
▼
e
Rollback
If an SQL error occurs, the program executes:
if con:
con.rollback()
If the Connection object exists, rollback() cancels temporary uncommitted changes.
DELETE │ ▼ Temporary Changes │ ▼ Database Error │ ▼ rollback() │ ▼ Cancel Uncommitted Changes
commit() vs rollback()
commit() |
rollback() |
|---|---|
| Saves changes permanently | Cancels uncommitted changes |
| Used after successful DELETE | Used if an error occurs |
con.commit() |
con.rollback() |
DELETE
│
▼
Transaction
/ \
/ \
▼ ▼
Success Error
│ │
▼ ▼
commit() rollback()
│ │
▼ ▼
Save Cancel
Display Error Message
The program displays the SQL error using:
print("There is a problem with sql :", e)
The general form of the output is:
There is a problem with sql : <Oracle Database Error>
The actual Oracle Database error information is available through e.
Finally Block
The finally block executes whether an exception occurs or not.
finally:
if cursor:
cursor.close()
if con:
con.close()
Its purpose is to release Database resources.
try
│
┌─────┴─────┐
│ │
Success Error
│ │
│ except
│ │
└─────┬─────┘
▼
finally
│
▼
Close Resources
Close Cursor
The Cursor is closed using:
if cursor:
cursor.close()
This releases the Cursor resource after the Database operation is completed.
Close Connection
The Database connection is closed using:
if con:
con.close()
This releases the Oracle Database connection.
Program Flow
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Read CutOff Salary
│
▼
Create DELETE SQL
│
▼
Execute DELETE Query
│
▼
Records Deleted Successfully
│
▼
Commit Changes
│
▼
Exception?
┌──┴──┐
│ │
No Yes
│ │
▼ ▼
Close Rollback
Resources Print Error
│ │
└──┬──┘
▼
Program Ends
Complete Successful Execution Flow
START
│
▼
import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Read CutOff Salary
│
▼
Create DELETE SQL
│
▼
cursor.execute()
│
▼
Check Each Matching
Employee Row
│
▼
esal > cutoffsalary?
/ \
Yes No
│ │
▼ ▼
Delete Row Keep Row
│ │
└───────┬───────┘
▼
Records Deleted Successfully
│
▼
con.commit()
│
▼
Save Deletion Permanently
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Complete Error Execution Flow
START
│
▼
Execute DELETE Query
│
▼
DatabaseError
│
▼
except cx_Oracle.DatabaseError as e
│
▼
if con
│
▼
con.rollback()
│
▼
Cancel Uncommitted Changes
│
▼
Print SQL Error
│
▼
finally
│
▼
cursor.close()
│
▼
con.close()
│
▼
END
Methods Used
| Method | Purpose |
|---|---|
connect() |
Creates a Database connection |
cursor() |
Creates a Cursor object |
execute() |
Executes the DELETE SQL statement |
commit() |
Permanently saves deleted records |
rollback() |
Cancels temporary changes if an error occurs |
close() |
Closes the Cursor and Connection |
Complete Program with Comments
main.py
No output captured.
Safer Version using Bind Variable
main.py
No output captured.
Original Tutorial Query vs Bind Variable
The original tutorial uses:
sql = "delete from employees where esal>%f" cursor.execute(sql % (cutoffsalary))
This is useful for understanding how the example in the tutorial works.
For real applications, a bind variable can be used:
sql = """
delete from employees
where esal > :cutoffsalary
"""
cursor.execute(
sql,
cutoffsalary=cutoffsalary
)
The SQL statement and the dynamic value are passed separately.
App7 UPDATE vs App8 DELETE
| Feature | App7 | App8 |
|---|---|---|
| Operation | UPDATE | DELETE |
| Purpose | Modify employee salaries | Remove employee records |
| Dynamic Input | Increment and salary range | Cutoff salary |
| Condition | esal < salrange |
esal > cutoffsalary |
| Execution | execute() |
execute() |
| Save Changes | commit() |
commit() |
| Error Recovery | rollback() |
rollback() |
Important Points
- App8 deletes employee records from the
employeestable. - The cutoff salary is entered dynamically from the keyboard.
- The cutoff value is stored in
cutoffsalary. float()converts the keyboard input into a floating-point value.- The SQL statement used is
DELETE. DELETEis a DML operation.- The SQL statement used in the tutorial is
delete from employees where esal>%f. - The
%fplaceholder represents the cutoff salary. - Only employees whose salary is greater than the entered cutoff salary are deleted.
- An employee whose salary is exactly equal to the cutoff salary is not deleted.
- The
WHEREclause determines which records are deleted. execute()executes the DELETE SQL statement.commit()is required to permanently save the deletion.rollback()cancels uncommitted changes if an error occurs.- The program uses
try-except-finallyfor exception handling. - The Cursor and Connection are closed in the
finallyblock.
Summary
| Topic | Description |
|---|---|
| Application | App8 |
| SQL Operation | Delete |
| Table | employees |
| Condition Column | esal |
| SQL Statement | delete from employees where esal>%f |
| Dynamic Input | Cutoff Salary |
| Variable | cutoffsalary |
| Condition | Employee salary greater than cutoff salary |
| Execution Method | execute() |
| Commit Required | Yes |
| Commit Method | con.commit() |
| Error Handling | rollback() |
| Exception | cx_Oracle.DatabaseError |
| Resource Cleanup | cursor.close() and con.close() |
Quick Revision
App8 │ ▼ DELETE Employee Records │ ▼ Read CutOff Salary │ ▼ DELETE FROM employees WHERE esal > cutoffsalary │ ▼ cursor.execute() │ ▼ Matching Employees Deleted │ ▼ con.commit() │ ▼ Deletion Saved If Error │ ▼ DatabaseError │ ▼ rollback() │ ▼ Cancel Changes Finally │ ▼ cursor.close() │ ▼ con.close()
Part 11 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Read CutOff Salary
│
▼
Create DELETE Query
│
▼
cursor.execute()
│
▼
Check WHERE Condition
│
esal > cutoffsalary?
/ \
Yes No
│ │
▼ ▼
Delete Record Keep Record
│ │
└──────┬───────┘
▼
Records Deleted Successfully
│
▼
commit()
│
▼
Save Changes Permanently
│
┌─────┴─────┐
│ │
Success Error
│ │
│ ▼
│ DatabaseError
│ │
│ ▼
│ rollback()
│ │
└─────┬─────┘
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 11 Completed
Next: Part 12 — App9: Select All Employee Information Using fetchone()
Introduction
In this application, we will learn how to retrieve employee information from the employees table using the fetchone() method.
The program first executes a SELECT query and then repeatedly calls fetchone() to retrieve employee records one by one.
This application demonstrates:
- Using the SQL
SELECTstatement - Using
cursor.execute() - Using
fetchone() - Fetching one row at a time
- Using
while row is not None - Processing the complete result set
- Handling Oracle Database errors
- Closing the Cursor and Connection
employees Table
│
▼
SELECT * FROM employees
│
▼
fetchone()
│
▼
One Employee Row
│
▼
Print Row
│
▼
fetchone()
│
▼
Next Employee Row
What is SELECT?
The SQL SELECT statement is used to retrieve data from a Database table.
General Syntax
SELECT column1, column2, ... FROM table_name;
To retrieve all columns:
SELECT * FROM table_name;
In this application, we use:
SELECT * FROM employees;
It retrieves all columns and all available rows from the employees table.
SELECT Operation in App9
The program executes:
cursor.execute("select * from employees")
Here:
| SQL Part | Meaning |
|---|---|
SELECT |
Retrieve data |
* |
Select all columns |
FROM |
Specifies the table |
employees |
Table from which records are retrieved |
What is fetchone()?
The fetchone() method is used to fetch only one row from the result set.
Each time fetchone() is called, it returns the next available row.
row = cursor.fetchone()
If another row is available:
fetchone()
│
▼
Next Row
If no more rows are available:
fetchone()
│
▼
None
Therefore, None indicates that the complete result set has been processed.
Important Behaviour of fetchone()
Suppose the result set contains four employee records:
Employee 1 Employee 2 Employee 3 Employee 4
Repeated calls to fetchone() behave like this:
| Call | Returned Value |
|---|---|
1st fetchone() |
Employee 1 |
2nd fetchone() |
Employee 2 |
3rd fetchone() |
Employee 3 |
4th fetchone() |
Employee 4 |
5th fetchone() |
None |
App9 — Program to Select All Employees Using fetchone()
main.py
No output captured.
Understanding the Program
The program performs the following operations:
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute SELECT Query
│
▼
fetchone()
│
▼
Row Available?
/ \
Yes No
│ │
▼ ▼
Print Row Stop
│
▼
fetchone()
│
└────────────► Repeat
Step 1 — Import the Module
The program starts by importing cx_Oracle:
import cx_Oracle
The cx_Oracle module is used to communicate between the Python program and Oracle Database.
Python │ ▼ cx_Oracle │ ▼ Oracle Database
Step 2 — Establish Database Connection
The connection is established using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection details used in the tutorial are:
| Property | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The returned Connection object is stored in:
con
Step 3 — Create Cursor Object
The Cursor object is created using:
cursor = con.cursor()
The Cursor object is required to execute SQL statements and fetch records returned by a query.
Connection
│
▼
cursor()
│
▼
Cursor Object
│
▼
Execute SQL
│
▼
Fetch Results
Step 4 — Execute SELECT Query
The program executes:
cursor.execute("select * from employees")
This SQL statement retrieves all records from the employees table.
SQL Query
SELECT * FROM employees;
The * means all columns.
If the employees table contains:
eno | ename | esal | eaddr
all four columns are included in the result set.
Understanding the Result Set
After executing the SELECT query, Oracle prepares the matching records as a result set.
cursor.execute("select * from employees")
│
▼
Result Set
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Row 1 Row 2 Row 3
fetchone() is then used to retrieve these rows one by one.
Step 5 — Fetch the First Row
The first row is retrieved using:
row = cursor.fetchone()
The fetchone() method retrieves one row from the result set.
The returned row is stored in:
row
For example:
row = (100, 'Sachin', 1000, 'Mumbai')
A Database row is normally represented as a tuple.
Understanding the row Variable
The row variable contains the employee record returned by fetchone().
For example:
(100, 'Sachin', 1000, 'Mumbai')
The values can be understood as:
| Index | Column | Example |
|---|---|---|
row[0] |
Employee Number | 100 |
row[1] |
Employee Name | Sachin |
row[2] |
Employee Salary | 1000 |
row[3] |
Employee Address | Mumbai |
Step 6 — Process Each Row
The program uses:
while row is not None:
The loop continues as long as row contains an employee record.
If:
row = (100, 'Sachin', 1000, 'Mumbai')
then:
row is not None
is True, so the loop executes.
When:
row = None
the condition becomes false and the loop terminates.
Why 'while row is not None' is Used
We do not know how many employee records may be available in the Database.
Therefore, the program keeps fetching rows until fetchone() returns None.
while row is not None:
print(row)
row = cursor.fetchone()
This makes the program work whether the table contains:
1 employee 10 employees 100 employees 1000 employees
The loop ends automatically after the last available row.
Step 7 — Print Current Employee Record
Inside the loop:
print(row)
prints the complete employee record.
For example:
(100, 'Sachin', 1000, 'Mumbai')
The complete tuple is displayed because the program prints row directly.
Step 8 — Fetch the Next Row
After printing the current row, the program executes:
row = cursor.fetchone()
This retrieves the next employee record.
Print Current Row
│
▼
cursor.fetchone()
│
▼
Get Next Row
│
▼
Check row is not None
This process continues until all employee records have been processed.
How fetchone() Works
SELECT Query
│
▼
fetchone()
│
▼
First Row
│
▼
Print Row
│
▼
fetchone()
│
▼
Second Row
│
▼
Print Row
│
▼
...
│
▼
fetchone()
│
▼
None
│
▼
Loop Ends
Example with Multiple Employee Records
Suppose the employees table contains:
+-----+--------+------+--------+ | eno | ename | esal | eaddr | +-----+--------+------+--------+ | 100 | Sachin | 1000 | Mumbai | | 200 | Dhoni | 2000 | Ranchi | | 300 | Kohli | 3000 | Delhi | +-----+--------+------+--------+
The SELECT query:
SELECT * FROM employees;
creates a result set containing these three rows.
fetchone() Call 1
The first statement:
row = cursor.fetchone()
returns:
(100, 'Sachin', 1000, 'Mumbai')
The condition:
row is not None
is true.
Therefore:
print(row)
prints:
(100, 'Sachin', 1000, 'Mumbai')
fetchone() Call 2
At the end of the first loop iteration:
row = cursor.fetchone()
returns the second record:
(200, 'Dhoni', 2000, 'Ranchi')
The loop condition is still true, so the second employee is printed.
fetchone() Call 3
The next call:
row = cursor.fetchone()
returns:
(300, 'Kohli', 3000, 'Delhi')
The third employee record is printed.
fetchone() Call 4 — No More Records
After processing the third employee, the program calls:
row = cursor.fetchone()
No more rows are available.
Therefore:
row = None
Now:
row is not None
becomes:
False
The while loop terminates.
Sample Output
For the example employee records, the output will be similar to:
(100, 'Sachin', 1000, 'Mumbai') (200, 'Dhoni', 2000, 'Ranchi') (300, 'Kohli', 3000, 'Delhi')
Each employee record is displayed one at a time.
What Happens if the Table is Empty?
If the employees table contains no records, the SELECT query returns an empty result set.
The first call:
row = cursor.fetchone()
returns:
None
Therefore:
while row is not None:
is false immediately.
The loop body does not execute.
SELECT │ ▼ No Rows │ ▼ fetchone() │ ▼ None │ ▼ Loop Does Not Execute
Does SELECT Require commit()?
This application only retrieves data using SELECT.
It does not insert, update, or delete employee records.
Therefore, the program does not call:
con.commit()
Compare:
| Operation | Changes Data? | commit() Normally Required? |
|---|---|---|
| INSERT | Yes | Yes |
| UPDATE | Yes | Yes |
| DELETE | Yes | Yes |
| SELECT | No | No |
Exception Handling
The program handles Oracle Database errors using:
except cx_Oracle.DatabaseError as e:
If a Database error occurs, execution moves to the except block.
The exception information is stored in:
e
Rollback
The exception block contains:
if con:
con.rollback()
If a Database error occurs, temporary uncommitted changes associated with the transaction can be rolled back.
The tutorial keeps this error-handling structure consistent with the previous Database applications.
Display Error Message
The error is displayed using:
print("There is a problem with sql :", e)
The actual Oracle Database error information is available in the exception object e.
Finally Block
The finally block executes whether the program succeeds or an exception occurs.
finally:
if cursor:
cursor.close()
if con:
con.close()
Its purpose is to release the Database resources.
try
│
┌────┴────┐
│ │
Success Exception
│ │
│ except
│ │
└────┬────┘
▼
finally
│
▼
Close Resources
Close Cursor
The Cursor is closed using:
if cursor:
cursor.close()
This releases the Cursor resource after all employee records have been processed.
Close Connection
The Database connection is closed using:
if con:
con.close()
This releases the connection with Oracle Database.
Program Flow
Import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
Execute SELECT Query
│
▼
fetchone()
│
▼
Row Available?
┌──┴──┐
│ │
Yes No
│ │
▼ ▼
Print End Loop
Row
│
▼
fetchone()
│
└──────────────► Repeat
│
▼
Close Resources
│
▼
Program Ends
Detailed Execution Flow
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
SELECT * FROM employees
│
▼
Execute Query
│
▼
fetchone()
│
▼
Store Row in row
│
▼
row is not None?
/ \
Yes No
│ │
▼ ▼
print(row) End Loop
│ │
▼ │
fetchone() │
│ │
└──── Repeat ──┘
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
fetchone() Execution Example
Result Set:
Row 1 → (100, 'Sachin', 1000, 'Mumbai')
Row 2 → (200, 'Dhoni', 2000, 'Ranchi')
Row 3 → (300, 'Kohli', 3000, 'Delhi')
│
▼
fetchone()
│
▼
Row 1
│
▼
Print Row 1
│
▼
fetchone()
│
▼
Row 2
│
▼
Print Row 2
│
▼
fetchone()
│
▼
Row 3
│
▼
Print Row 3
│
▼
fetchone()
│
▼
None
│
▼
Loop Ends
Methods Used
| Method | Purpose |
|---|---|
connect() |
Creates a Database connection |
cursor() |
Creates a Cursor object |
execute() |
Executes the SELECT SQL statement |
fetchone() |
Retrieves one row at a time from the result set |
rollback() |
Rolls back temporary changes if an error occurs |
close() |
Closes the Cursor and Connection |
Complete Program with Comments
main.py
No output captured.
fetchone() vs execute()
execute() and fetchone() perform different operations.
| Method | Purpose |
|---|---|
execute() |
Executes the SQL query |
fetchone() |
Retrieves the next row from the query result |
execute() │ ▼ Run SELECT Query │ ▼ Result Set │ ▼ fetchone() │ ▼ One Row
fetchone() vs fetchall()
fetchone() retrieves one row at a time, whereas fetchall() retrieves all available rows at once.
| fetchone() | fetchall() |
|---|---|
| Returns one row | Returns all rows |
| Called repeatedly | Usually called once |
| Returns the next available row | Returns a collection of all rows |
Returns None when no row remains |
Returns all remaining result rows |
| Used with a loop in App9 | Used in the next application |
Important Points
- App9 retrieves employee information from the
employeestable. - The program uses
SELECT * FROM employees. - The
*selects all columns. execute()executes the SELECT query.fetchone()returns only one row at a time.- Every call to
fetchone()returns the next available row. - The returned row is stored in the variable
row. - A fetched Database row is represented as a tuple.
- When no more rows are available,
fetchone()returnsNone. - The
while row is not Noneloop is used to display all employee records. - The loop repeatedly calls
fetchone(). - The program prints one employee record at a time.
SELECTonly retrieves data, so this program does not requirecommit()for the SELECT operation.- Oracle Database errors are handled using
cx_Oracle.DatabaseError. - The Cursor and Connection are closed in the
finallyblock.
Summary
| Topic | Description |
|---|---|
| Application | App9 |
| SQL Operation | Select |
| SQL Statement | SELECT * FROM employees |
| Table | employees |
| Execution Method | execute() |
| Fetch Method | fetchone() |
| Rows Returned | One row at a time |
| End Value | None |
| Loop Used | while row is not None |
| Commit Required for SELECT | No |
| Error Handling | rollback() |
| Exception | cx_Oracle.DatabaseError |
| Resource Cleanup | cursor.close() and con.close() |
Quick Revision
App9
│
▼
SELECT Employee Records
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
fetchone()
│
▼
One Row
│
▼
row is not None?
│
├── Yes → Print Row
│ │
│ ▼
│ fetchone()
│ │
│ └──── Repeat
│
└── No → Loop Ends
│
▼
Close Cursor
│
▼
Close Connection
Part 12 - Final Concept
START
│
▼
import cx_Oracle
│
▼
Create Connection
│
▼
Create Cursor
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
fetchone()
│
▼
Store Result in row
│
▼
row is not None?
/ \
Yes No
│ │
▼ ▼
print(row) End Loop
│ │
▼ │
fetchone() │
│ │
└──── Repeat ──┘
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 12 Completed
Next: Part 13 — App10: Select All Employee Information Using fetchall()
Introduction
In the previous application, we used fetchone() to retrieve employee records one by one.
In this application, we will learn how to retrieve all employee records at once from the employees table using the fetchall() method.
The program first executes a SELECT query and then calls fetchall() to retrieve all remaining rows from the result set.
This application demonstrates:
- Using the SQL
SELECTstatement - Using
cursor.execute() - Using
fetchall() - Retrieving all employee rows at once
- Understanding the collection returned by
fetchall() - Using a
forloop to process employee records - Accessing individual column values from each row
- Handling Oracle Database errors
- Closing the Cursor and Connection
employees Table
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
Result Set
│
▼
fetchall()
│
▼
All Employee Rows
│
▼
for row in rows
│
▼
Print Each Employee
What is fetchall()?
The fetchall() method is used to retrieve all remaining rows from the result set.
Syntax
rows = cursor.fetchall()
After executing a SELECT query, fetchall() collects all available rows and returns them together.
SELECT Query
│
▼
Result Set
│
├── Row 1
├── Row 2
├── Row 3
└── Row 4
│
▼
fetchall()
│
▼
[Row 1, Row 2, Row 3, Row 4]
Each individual row is normally represented as a tuple.
Return Value of fetchall()
fetchall() returns all remaining result rows as a collection.
For example:
[
(100, 'Sachin', 1000, 'Mumbai'),
(200, 'Dhoni', 2000, 'Ranchi'),
(300, 'Kohli', 3000, 'Delhi')
]
Here:
- The outer collection contains all employee records.
- Each inner tuple represents one employee record.
- Each value inside a tuple represents one column value.
All Rows │ ├── (100, 'Sachin', 1000, 'Mumbai') │ ├── (200, 'Dhoni', 2000, 'Ranchi') │ └── (300, 'Kohli', 3000, 'Delhi')
App10 — Complete Program
main.py
No output captured.
Understanding the Program
The complete program performs the following operations:
Import cx_Oracle
│
▼
Connect to Oracle Database
│
▼
Create Cursor
│
▼
Execute SELECT Query
│
▼
fetchall()
│
▼
Store All Rows in data
│
▼
for row in data
│
▼
Print Each Row
│
▼
Close Resources
Step 1 — Import cx_Oracle
The program starts with:
import cx_Oracle
The cx_Oracle module provides the functionality required to communicate with Oracle Database from Python.
Python Program
│
▼
cx_Oracle
│
▼
Oracle Database
Step 2 — Establish Database Connection
The program establishes a connection using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection information used in the tutorial is:
| Property | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The returned Connection object is stored in:
con
Step 3 — Create Cursor Object
The Cursor object is created using:
cursor = con.cursor()
The Cursor object is used for:
- Executing SQL statements
- Maintaining the query result
- Fetching records from the result set
Connection
│
▼
con.cursor()
│
▼
Cursor
│
├── execute()
│
└── fetchall()
Step 4 — Execute SELECT Query
The program executes:
cursor.execute("select * from employees")
The equivalent SQL statement is:
SELECT * FROM employees;
This query retrieves all columns and all available employee records from the employees table.
| SQL Part | Meaning |
|---|---|
SELECT |
Retrieve data |
* |
Retrieve all columns |
FROM |
Specifies the source table |
employees |
Table containing employee records |
Understanding SELECT *
The * symbol in:
SELECT * FROM employees
means that all columns should be retrieved.
Suppose the table contains:
eno ename esal eaddr
Then each returned employee row contains values for all these columns.
For example:
(100, 'Sachin', 1000, 'Mumbai')
Step 5 — Fetch All Records
After executing the SELECT query, the program calls:
data = cursor.fetchall()
fetchall() retrieves all remaining rows from the query result.
The returned collection is stored in:
data
For example:
data = [
(100, 'Sachin', 1000, 'Mumbai'),
(200, 'Dhoni', 2000, 'Ranchi'),
(300, 'Kohli', 3000, 'Delhi')
]
Understanding the data Variable
The variable data contains all employee records returned by fetchall().
data │ ├── Employee Row 1 ├── Employee Row 2 ├── Employee Row 3 └── ...
Each employee row can then be processed separately using a loop.
Step 6 — Iterate through All Records
The program uses a for loop:
for row in data:
print(row)
During every iteration, one employee tuple from data is assigned to row.
data │ ├── Row 1 ──► row ──► print() │ ├── Row 2 ──► row ──► print() │ └── Row 3 ──► row ──► print()
The loop automatically stops after processing the final employee record.
Understanding the row Variable
Inside the loop:
for row in data:
row represents one employee record.
For example:
row = (100, 'Sachin', 1000, 'Mumbai')
The individual values can be accessed using indexes:
| Expression | Meaning | Example Value |
|---|---|---|
row[0] |
Employee Number | 100 |
row[1] |
Employee Name | Sachin |
row[2] |
Employee Salary | 1000 |
row[3] |
Employee Address | Mumbai |
Step 7 — Print Each Employee Record
The statement:
print(row)
prints the complete employee tuple.
For example:
(100, 'Sachin', 1000, 'Mumbai')
Because the statement is inside the for loop, every employee record is displayed.
Example — Employees Table
Suppose the employees table contains:
+-----+--------+------+--------+ | eno | ename | esal | eaddr | +-----+--------+------+--------+ | 100 | Sachin | 1000 | Mumbai | | 200 | Dhoni | 2000 | Ranchi | | 300 | Kohli | 3000 | Delhi | | 400 | Rohit | 4000 | Mumbai | +-----+--------+------+--------+
The query:
SELECT * FROM employees;
retrieves all four records.
Example — Result of fetchall()
After:
data = cursor.fetchall()
the conceptual value of data is:
[
(100, 'Sachin', 1000, 'Mumbai'),
(200, 'Dhoni', 2000, 'Ranchi'),
(300, 'Kohli', 3000, 'Delhi'),
(400, 'Rohit', 4000, 'Mumbai')
]
Unlike fetchone(), we do not have to call fetchall() separately for every employee.
Example — for Loop Execution
The loop:
for row in data:
print(row)
executes as follows:
Iteration 1 row = (100, 'Sachin', 1000, 'Mumbai') print(row) Iteration 2 row = (200, 'Dhoni', 2000, 'Ranchi') print(row) Iteration 3 row = (300, 'Kohli', 3000, 'Delhi') print(row) Iteration 4 row = (400, 'Rohit', 4000, 'Mumbai') print(row) Loop Ends
Sample Output
The output will be similar to:
(100, 'Sachin', 1000, 'Mumbai') (200, 'Dhoni', 2000, 'Ranchi') (300, 'Kohli', 3000, 'Delhi') (400, 'Rohit', 4000, 'Mumbai')
Each row is displayed as a tuple.
Displaying Individual Column Values
Instead of printing the complete tuple:
print(row)
we can access individual values:
for row in data:
print("Employee Number :", row[0])
print("Employee Name :", row[1])
print("Employee Salary :", row[2])
print("Employee Address:", row[3])
For one employee:
Employee Number : 100 Employee Name : Sachin Employee Salary : 1000 Employee Address: Mumbai
Complete Program — Display Individual Columns
main.py
No output captured.
What Happens if the Table is Empty?
If the employees table does not contain any records, the SELECT query produces no rows.
In that case:
data = cursor.fetchall()
returns an empty collection:
[]
Then:
for row in data:
print(row)
does not execute even once.
SELECT Query
│
▼
No Records
│
▼
fetchall()
│
▼
[]
│
▼
for Loop
│
▼
0 Iterations
Does SELECT Require commit()?
No. The SELECT statement retrieves data but does not modify the table.
Therefore, App10 does not require:
con.commit()
for retrieving employee records.
| SQL Operation | Modifies Data? | commit() Normally Required? |
|---|---|---|
| INSERT | Yes | Yes |
| UPDATE | Yes | Yes |
| DELETE | Yes | Yes |
| SELECT | No | No |
Exception Handling
Oracle Database errors are handled using:
except cx_Oracle.DatabaseError as e:
If a Database error occurs, control moves from the try block to the except block.
The exception information is stored in:
e
For example, an error can occur if:
- The Database connection fails
- The table does not exist
- The SQL query is invalid
- The Database server is unavailable
Rollback
The tutorial's standard Database error-handling structure contains:
if con:
con.rollback()
rollback() is mainly important when uncommitted DML changes exist.
App10 itself performs only a SELECT operation, so it does not modify employee data.
Display Error Message
The Database error is displayed using:
print("There is a problem with sql :", e)
The actual Oracle error information is available through the exception object e.
Finally Block
The finally block is used to close Database resources.
finally:
if cursor:
cursor.close()
if con:
con.close()
The finally block executes whether the Database operation succeeds or fails.
try
│
┌─────┴─────┐
│ │
Success Error
│ │
│ except
│ │
└─────┬─────┘
▼
finally
│
▼
Close Resources
Close Cursor
The Cursor is closed using:
if cursor:
cursor.close()
Closing the Cursor releases resources associated with SQL execution and result processing.
Close Connection
The Database connection is closed using:
if con:
con.close()
This releases the connection between the Python program and Oracle Database.
Complete Execution Flow
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
Result Set
│
▼
cursor.fetchall()
│
▼
Store Rows in data
│
▼
for row in data
│
▼
print(row)
│
▼
More Rows Available?
/ \
Yes No
│ │
└── Repeat ▼
End Loop
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
fetchone() vs fetchall()
App9 used fetchone(), whereas App10 uses fetchall().
| Feature | fetchone() | fetchall() |
|---|---|---|
| Rows Retrieved | One row | All remaining rows |
| Return | Single row or None |
Collection of rows |
| Repeated Fetching | Usually required | Not required to obtain all rows |
| Loop Style | Often while |
Often for |
| No Rows | None |
Empty collection |
| Memory Usage | Can process rows individually | Loads all remaining rows into memory |
App9 vs App10 Program Flow
App9 — fetchone()
SELECT │ ▼ fetchone() │ ▼ One Row │ ▼ Print │ ▼ fetchone() │ ▼ Next Row
App10 — fetchall()
SELECT │ ▼ fetchall() │ ▼ All Rows │ ▼ for Loop │ ▼ Print Each Row
Important Difference for Large Result Sets
fetchall() is simple when we want to retrieve all records together.
However, it retrieves all remaining rows into memory.
Therefore, if a query returns a very large number of records, fetching and storing all of them together can require more memory.
Small Result Set
│
▼
fetchall()
│
▼
Simple and Convenient
Very Large Result Set
│
▼
fetchall()
│
▼
More Memory Required
For large result sets, processing records in smaller groups or one by one can be more memory-friendly.
Methods Used
| Method | Purpose |
|---|---|
connect() |
Establishes connection with Oracle Database |
cursor() |
Creates a Cursor object |
execute() |
Executes the SELECT query |
fetchall() |
Retrieves all remaining records |
rollback() |
Rolls back uncommitted changes when applicable |
close() |
Closes Database resources |
Complete Program with Comments
main.py
No output captured.
Important Points
- App10 retrieves employee information from the
employeestable. - The program uses the SQL query
SELECT * FROM employees. *represents all columns.execute()executes the SELECT query.fetchall()retrieves all remaining rows from the result set.- All fetched employee records are stored in the variable
data. - Each individual employee row is normally represented as a tuple.
- A
forloop can be used to process each employee record. row[0],row[1], etc. can be used to access individual column values.- If no records are available,
fetchall()returns an empty collection. fetchall()is different fromfetchone().fetchone()retrieves one row at a time.fetchall()retrieves all remaining rows together.- A SELECT operation does not normally require
commit(). fetchall()can consume more memory when the result set is very large.- Database errors are handled using
cx_Oracle.DatabaseError. - The Cursor and Connection should be closed after use.
Summary
| Topic | Description |
|---|---|
| Application | App10 |
| Purpose | Select all employee records |
| SQL Operation | SELECT |
| SQL Query | SELECT * FROM employees |
| Table | employees |
| Execution Method | execute() |
| Fetch Method | fetchall() |
| Rows Retrieved | All remaining rows |
| Storage Variable | data |
| Loop | for row in data |
| No Records | Empty collection |
| Commit Required | No for SELECT |
| Exception | cx_Oracle.DatabaseError |
| Cleanup | cursor.close() and con.close() |
Quick Revision
App10 │ ▼ SELECT Employee Data │ ▼ SELECT * FROM employees │ ▼ cursor.execute() │ ▼ fetchall() │ ▼ All Rows │ ▼ data │ ▼ for row in data │ ▼ print(row) │ ▼ Repeat for Every Row │ ▼ Close Cursor │ ▼ Close Connection
Part 13 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
Result Set
│
▼
cursor.fetchall()
│
▼
Store All Rows in data
│
▼
for row in data
│
▼
print(row)
│
▼
More Records?
/ \
Yes No
│ │
└─ Repeat ▼
End Loop
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 13 Completed
In this application, we learned how to retrieve all employee records using fetchall() and process the returned rows using a for loop.
Next: Part 14 — App11: Select Employee Data using Cursor Iteration
Introduction
In the previous applications, we learned how to retrieve Database records using fetchone() and fetchall().
In this application, we will learn how to retrieve a specified number of employee records at a time using the fetchmany() method.
The fetchmany() method is useful when we do not want to retrieve all records at once.
This application demonstrates:
- Using the SQL
SELECTstatement - Using
cursor.execute() - Using
fetchmany() - Retrieving a specified number of records
- Understanding the
sizeargument - Processing returned employee records
- Calling
fetchmany()multiple times - Understanding what happens when fewer records remain
- Understanding what happens when no records remain
- Comparing
fetchone(),fetchmany(), andfetchall() - Handling Oracle Database errors
- Closing Database resources
employees Table
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
Result Set
│
▼
fetchmany(size)
│
▼
Specified Number of Rows
│
▼
Process Rows
What is fetchmany()?
The fetchmany() method is used to retrieve a specified number of rows from the result set.
Syntax
cursor.fetchmany(size)
Here, size represents the maximum number of rows that should be fetched.
Example:
data = cursor.fetchmany(3)
This asks the Cursor to fetch up to 3 rows from the current position of the result set.
Result Set │ ├── Row 1 ─┐ ├── Row 2 ├── fetchmany(3) ├── Row 3 ─┘ ├── Row 4 └── Row 5
Why do we use fetchmany()?
fetchmany() provides a middle approach between fetchone() and fetchall().
fetchone()
│
▼
One Row
fetchmany(n)
│
▼
Specified Number of Rows
fetchall()
│
▼
All Remaining Rows
If a query returns many records, we may not want to load all of them at once.
With fetchmany(), records can be processed in smaller batches.
Syntax of fetchmany()
Syntax
cursor.fetchmany(size)
Example:
cursor.fetchmany(2)
This returns up to two rows.
Another example:
cursor.fetchmany(5)
This returns up to five rows.
| Statement | Maximum Rows Requested |
|---|---|
fetchmany(1) |
1 |
fetchmany(2) |
2 |
fetchmany(5) |
5 |
fetchmany(10) |
10 |
Understanding the size Argument
The number passed to fetchmany() specifies the maximum number of records to retrieve.
For example:
data = cursor.fetchmany(3)
Here:
size = 3
Therefore, Python requests up to three rows from the current Cursor position.
If three or more records are available, three records are returned.
If fewer than three records remain, only the remaining records are returned.
App11 — Complete Program
main.py
No output captured.
Program Explanation
The program performs the following operations:
Import cx_Oracle
│
▼
Connect to Oracle Database
│
▼
Create Cursor
│
▼
Execute SELECT Query
│
▼
fetchmany(3)
│
▼
Fetch Up to 3 Records
│
▼
Store Records in data
│
▼
for row in data
│
▼
Print Each Row
│
▼
Close Resources
Step 1 — Import cx_Oracle
The program imports the Oracle Database module:
import cx_Oracle
cx_Oracle provides the classes and methods required to communicate with Oracle Database.
Python │ ▼ cx_Oracle │ ▼ Oracle Database
Step 2 — Establish Database Connection
The connection is established using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection information used in the tutorial is:
| Property | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
The returned Connection object is stored in:
con
Step 3 — Create Cursor Object
The Cursor object is created using:
cursor = con.cursor()
The Cursor is used to execute SQL queries and retrieve the resulting records.
Connection
│
▼
con.cursor()
│
▼
Cursor
│
├── execute()
├── fetchone()
├── fetchmany()
└── fetchall()
Step 4 — Execute SELECT Query
The SELECT query is executed using:
cursor.execute("select * from employees")
The equivalent SQL query is:
SELECT * FROM employees;
This retrieves all available employee rows and columns into the query result set.
| SQL Part | Meaning |
|---|---|
SELECT |
Retrieve data |
* |
All columns |
FROM |
Specifies source table |
employees |
Employee table |
Step 5 — Fetch Multiple Employee Records
The important statement in App11 is:
data = cursor.fetchmany(3)
This retrieves up to three employee records from the result set.
The returned rows are stored in:
data
For example:
data = [
(100, 'Sachin', 1000, 'Mumbai'),
(200, 'Dhoni', 2000, 'Ranchi'),
(300, 'Kohli', 3000, 'Delhi')
]
How fetchmany(3) Works
Suppose the query result contains six employee records:
Row 1 Row 2 Row 3 Row 4 Row 5 Row 6
When we execute:
data = cursor.fetchmany(3)
the first three rows are returned:
Row 1 Row 2 Row 3
The Cursor position moves forward.
Before fetchmany(3) Cursor │ ▼ Row 1 Row 2 Row 3 Row 4 Row 5 Row 6 After fetchmany(3) Fetched: Row 1 Row 2 Row 3 Remaining: Row 4 Row 5 Row 6
Understanding Cursor Position
A very important point is that fetching records changes the current Cursor position in the result set.
Suppose:
Result Set: Row 1 Row 2 Row 3 Row 4 Row 5 Row 6
After:
cursor.fetchmany(3)
Rows 1, 2 and 3 have already been fetched.
The next fetch operation starts from Row 4.
Row 1 ✓ Fetched Row 2 ✓ Fetched Row 3 ✓ Fetched ------------------ Row 4 ← Next Cursor Position Row 5 Row 6
Step 6 — Process Returned Records
The program processes the returned rows using:
for row in data:
print(row)
During each iteration, one employee tuple is assigned to row.
data │ ├── Row 1 ──► row ──► print() │ ├── Row 2 ──► row ──► print() │ └── Row 3 ──► row ──► print()
Understanding Each Employee Row
Suppose one returned employee record is:
(100, 'Sachin', 1000, 'Mumbai')
The individual values can be accessed using indexes:
| Expression | Meaning | Example |
|---|---|---|
row[0] |
Employee Number | 100 |
row[1] |
Employee Name | Sachin |
row[2] |
Employee Salary | 1000 |
row[3] |
Employee Address | Mumbai |
Example — Employees Table
Suppose the employees table contains:
+-----+--------+------+-----------+ | eno | ename | esal | eaddr | +-----+--------+------+-----------+ | 100 | Sachin | 1000 | Mumbai | | 200 | Dhoni | 2000 | Ranchi | | 300 | Kohli | 3000 | Delhi | | 400 | Rohit | 4000 | Mumbai | | 500 | Rahul | 5000 | Bangalore | | 600 | Hardik | 6000 | Baroda | +-----+--------+------+-----------+
The query:
SELECT * FROM employees;
produces six employee records.
Example — First fetchmany(3)
Now execute:
data = cursor.fetchmany(3)
The first three records are returned:
[
(100, 'Sachin', 1000, 'Mumbai'),
(200, 'Dhoni', 2000, 'Ranchi'),
(300, 'Kohli', 3000, 'Delhi')
]
The output from:
for row in data:
print(row)
will be:
(100, 'Sachin', 1000, 'Mumbai') (200, 'Dhoni', 2000, 'Ranchi') (300, 'Kohli', 3000, 'Delhi')
Calling fetchmany() Again
fetchmany() can be called multiple times on the same result set.
For example:
data1 = cursor.fetchmany(3) data2 = cursor.fetchmany(3)
The first call retrieves:
Row 1 Row 2 Row 3
The second call continues from the current Cursor position and retrieves:
Row 4 Row 5 Row 6
Result Set │ ├── Row 1 ─┐ ├── Row 2 ├── First fetchmany(3) ├── Row 3 ─┘ │ ├── Row 4 ─┐ ├── Row 5 ├── Second fetchmany(3) └── Row 6 ─┘
Demo — Multiple fetchmany() Calls
main.py
No output captured.
Output — Multiple fetchmany() Calls
For six employee records, the output will be similar to:
First Batch: (100, 'Sachin', 1000, 'Mumbai') (200, 'Dhoni', 2000, 'Ranchi') (300, 'Kohli', 3000, 'Delhi') Second Batch: (400, 'Rohit', 4000, 'Mumbai') (500, 'Rahul', 5000, 'Bangalore') (600, 'Hardik', 6000, 'Baroda')
The second call does not start again from the first employee.
It continues from the current Cursor position.
What if Fewer Records Remain?
The number passed to fetchmany() represents the maximum number of rows requested.
Suppose only two rows remain:
Row 5 Row 6
and we execute:
data = cursor.fetchmany(3)
Only the two remaining records are returned.
Requested = 3 Available = 2 Returned = 2
fetchmany() does not create an error simply because fewer rows are available.
Example — Fewer Rows than Requested
Suppose five employees exist and we fetch records in groups of three.
Total Records = 5 Batch Size = 3
First Call
cursor.fetchmany(3) Returns: Row 1 Row 2 Row 3
Second Call
cursor.fetchmany(3) Returns: Row 4 Row 5
Although three records were requested, only two records remained.
What Happens When No Records Remain?
After all records have been fetched, another call to fetchmany() returns an empty collection.
For example:
data = cursor.fetchmany(3)
When there are no remaining records:
data = []
No Remaining Rows
│
▼
fetchmany(3)
│
▼
[]
Example — Complete Batch Fetching
Suppose there are seven employee records and the batch size is three.
First Call
fetchmany(3) Row 1 Row 2 Row 3
Second Call
fetchmany(3) Row 4 Row 5 Row 6
Third Call
fetchmany(3) Row 7
Fourth Call
fetchmany(3) []
This shows how fetchmany() can be used to process a result set in batches.
Fetch All Records in Batches
We can repeatedly call fetchmany() until it returns an empty collection.
For example:
while True:
data = cursor.fetchmany(3)
if not data:
break
for row in data:
print(row)
This approach retrieves employee records in groups of three.
fetchmany(3)
│
▼
Batch Returned?
/ \
Yes No
│ │
▼ ▼
Process Stop
Batch
│
▼
fetchmany(3)
│
└──────────► Repeat
Complete Program — Fetch Records in Batches
main.py
No output captured.
Execution Flow of Batch Program
START
│
▼
Execute SELECT Query
│
▼
fetchmany(3)
│
▼
data Available?
/ \
Yes No
│ │
▼ ▼
for row in data break
│ │
▼ │
print(row) │
│ │
▼ │
Process All Rows │
in Current Batch │
│ │
└─────┐ │
│ │
▼ │
fetchmany(3) │
│ │
└───────┘
│
▼
END
Displaying Individual Column Values
Instead of displaying the complete tuple:
print(row)
we can access individual values:
for row in data:
print("Employee Number :", row[0])
print("Employee Name :", row[1])
print("Employee Salary :", row[2])
print("Employee Address:", row[3])
Example output:
Employee Number : 100 Employee Name : Sachin Employee Salary : 1000 Employee Address: Mumbai
fetchone() vs fetchmany() vs fetchall()
| Feature | fetchone() | fetchmany() | fetchall() |
|---|---|---|---|
| Purpose | Fetch one row | Fetch specified number of rows | Fetch all remaining rows |
| Example | fetchone() |
fetchmany(3) |
fetchall() |
| Return | Single row | Collection of rows | Collection of rows |
| No More Rows | None |
Empty collection | Empty collection |
| Batch Size | 1 | Specified by programmer | All remaining rows |
| Large Result Sets | Can process one by one | Useful for batch processing | Can require more memory |
Visual Comparison
Result Set:
R1 R2 R3 R4 R5 R6 R7
│
├── fetchone()
│ │
│ └── R1
│
├── fetchmany(3)
│ │
│ └── R1 R2 R3
│
└── fetchall()
│
└── R1 R2 R3 R4 R5 R6 R7
All three methods work with records produced by a SELECT query, but they differ in how many rows they retrieve at one time.
Does SELECT Require commit()?
The program performs only a SELECT operation.
SELECT retrieves data and does not modify employee records.
Therefore, commit() is not required for this SELECT operation.
| Operation | Modifies Data? | commit() Normally Required? |
|---|---|---|
| INSERT | Yes | Yes |
| UPDATE | Yes | Yes |
| DELETE | Yes | Yes |
| SELECT | No | No |
Exception Handling
The program handles Oracle Database errors using:
except cx_Oracle.DatabaseError as e:
If an Oracle Database error occurs, control moves to the except block.
The error information is stored in:
e
Possible errors include:
- Invalid Database connection
- Invalid username or password
- Database server unavailable
- Employees table does not exist
- Invalid SQL statement
Rollback
The standard error-handling structure used in the tutorial may contain:
if con:
con.rollback()
rollback() is important when there are uncommitted DML changes.
App11 itself performs only a SELECT query, so it does not modify employee data.
Finally Block
The finally block executes whether the program succeeds or an exception occurs.
finally:
if cursor:
cursor.close()
if con:
con.close()
It ensures that Database resources are released.
try
│
┌─────┴─────┐
│ │
Success Error
│ │
│ except
│ │
└─────┬─────┘
▼
finally
│
▼
Close Resources
Close Cursor
The Cursor is closed using:
if cursor:
cursor.close()
This releases resources associated with SQL execution and result fetching.
Close Connection
The Oracle Database connection is closed using:
if con:
con.close()
This releases the connection between the Python application and Oracle Database.
Complete Program with Comments
main.py
No output captured.
Complete Execution Flow
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
Result Set
│
▼
cursor.fetchmany(3)
│
▼
Fetch Up to 3 Rows
│
▼
Store in data
│
▼
for row in data
│
▼
print(row)
│
▼
More Rows in
Current Batch?
/ \
Yes No
│ │
└─ Repeat ▼
End Loop
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Methods Used
| Method | Purpose |
|---|---|
connect() |
Establishes a connection with Oracle Database |
cursor() |
Creates a Cursor object |
execute() |
Executes the SELECT query |
fetchmany(size) |
Retrieves up to the specified number of rows |
rollback() |
Rolls back uncommitted changes when applicable |
close() |
Closes Database resources |
Important Points
- App11 retrieves employee data using
fetchmany(). - The SQL query used is
SELECT * FROM employees. execute()executes the SELECT query.fetchmany(size)retrieves up to the specified number of rows.- The number passed to
fetchmany()represents the maximum number of rows requested. fetchmany(3)requests up to three rows.- The returned records are stored in a collection.
- Each individual employee record is normally represented as a tuple.
- A
forloop can be used to process the fetched records. - The Cursor remembers its current position in the result set.
- A second call to
fetchmany()continues from where the previous fetch operation stopped. - If fewer rows remain than requested, only the remaining rows are returned.
- If no rows remain,
fetchmany()returns an empty collection. fetchone()retrieves one row at a time.fetchmany()retrieves rows in batches.fetchall()retrieves all remaining rows.fetchmany()can be useful when processing large result sets in smaller batches.- SELECT does not normally require
commit(). - Database errors are handled using
cx_Oracle.DatabaseError. - The Cursor and Connection should be closed after use.
Summary
| Topic | Description |
|---|---|
| Application | App11 |
| Purpose | Select employee records in batches |
| SQL Operation | SELECT |
| SQL Query | SELECT * FROM employees |
| Table | employees |
| Execution Method | execute() |
| Fetch Method | fetchmany() |
| Example | fetchmany(3) |
| Rows Retrieved | Up to the specified size |
| Returned Value | Collection of rows |
| No More Rows | Empty collection |
| Processing | for loop |
| Cursor Position | Continues from the previous fetch |
| Commit Required | No for SELECT |
| Exception | cx_Oracle.DatabaseError |
| Cleanup | cursor.close() and con.close() |
Quick Revision
App11 │ ▼ SELECT Employee Data │ ▼ SELECT * FROM employees │ ▼ cursor.execute() │ ▼ fetchmany(3) │ ▼ Up to 3 Rows │ ▼ data │ ▼ for row in data │ ▼ print(row) │ ▼ Process Current Batch │ ▼ Close Cursor │ ▼ Close Connection
Part 14 - Final Concept
START
│
▼
import cx_Oracle
│
▼
try
│
▼
Create Connection
│
▼
Create Cursor
│
▼
SELECT * FROM employees
│
▼
cursor.execute()
│
▼
Result Set
│
▼
fetchmany(size)
│
▼
Fetch Up to 'size' Rows
│
▼
data
│
▼
for row in data
│
▼
print(row)
│
▼
Current Batch Ends
│
▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Part 14 Completed
In this application, we learned how fetchmany() retrieves a specified number of employee records from a SELECT query result.
We also learned how repeated fetchmany() calls continue from the current Cursor position and how the method behaves when fewer or no records remain.
Introduction
Until now, we have discussed Python Database Programming with Oracle Database.
Now we will learn how to work with another popular relational Database called MySQL.
MySQL is a widely used Relational Database Management System (RDBMS).
It is used to store, organize, retrieve, update and manage data in the form of tables.
In this part, we will understand:
- What is MySQL?
- What is a Database?
- What is an RDBMS?
- Important features of MySQL
- MySQL Database Server
- MySQL Client
- How to connect to MySQL
- Default MySQL Databases
- How to display available Databases
- How to create a Database
- How to select a Database
- How to check the currently selected Database
- How to create a table
- How to display tables
- How to view table structure
- How to insert records
- How to retrieve records
- How to drop a table
- How to drop a Database
- Important MySQL commands
Python Application
│
▼
MySQL Driver
│
▼
MySQL Server
│
▼
Database
│
▼
Table
│
▼
Data
What is MySQL?
MySQL is a popular open-source Relational Database Management System.
It is used to manage structured data using tables.
MySQL uses SQL — Structured Query Language for performing Database operations.
Simple Definition
MySQL is an RDBMS used to store and manage data in the form of related tables.
For example, an organization can maintain:
Company Database
│
├── employees
├── departments
├── customers
├── products
└── orders
Each table stores information related to a particular entity.
What is a Database?
A Database is an organized collection of related data.
For example, consider employee information:
Employee Number Employee Name Employee Salary Employee Address
Instead of maintaining this information in separate files, we can store it systematically inside a Database.
Database │ ▼ employees Table │ ├── Employee 1 ├── Employee 2 ├── Employee 3 └── Employee 4
What is RDBMS?
RDBMS stands for:
Relational Database Management System
In an RDBMS, data is mainly organized into tables consisting of rows and columns.
employees +------+--------+--------+ | eno | ename | esal | +------+--------+--------+ | 100 | Sachin | 50000 | | 200 | Dhoni | 60000 | | 300 | Kohli | 70000 | +------+--------+--------+
Here:
- employees is the table.
- eno, ename and esal are columns.
- Each horizontal entry is a row or record.
MySQL as an RDBMS
MySQL is called a Relational Database Management System because it stores information in tables and supports relationships between tables.
For example:
Department Table
│
│ Relationship
▼
Employee Table
Different tables can be related using keys such as:
- Primary Key
- Foreign Key
This relational structure makes it easier to organize and manage large amounts of structured data.
SQL and MySQL
SQL and MySQL are not exactly the same thing.
| SQL | MySQL |
|---|---|
| Structured Query Language | Relational Database Management System |
| A language | Database software |
| Used to communicate with relational Databases | Uses SQL for Database operations |
For example:
SELECT * FROM employees;
This is an SQL statement that can be executed by MySQL.
Features of MySQL
MySQL provides several important features.
- MySQL is a Relational Database Management System.
- It supports SQL.
- It is available as open-source software, with commercial offerings also available.
- It follows a client-server architecture.
- It supports multiple users.
- It can manage multiple Databases.
- It supports tables, rows and columns.
- It supports primary keys and foreign keys.
- It supports indexes.
- It supports views.
- It supports stored procedures.
- It supports triggers.
- It supports transactions with transactional storage engines such as InnoDB.
- It provides security and user-management features.
- It can be accessed from programming languages such as Python.
- It is available on multiple operating systems.
MySQL Client-Server Architecture
MySQL generally follows a client-server architecture.
The MySQL Server manages Databases, while clients send requests to the Server.
MySQL Server
│
┌────────┼────────┐
│ │ │
▼ ▼ ▼
Client 1 Client 2 Client 3
│ │ │
Python CLI Workbench
Examples of MySQL clients include:
- MySQL command-line client
- MySQL Workbench
- Python applications
- Web applications
MySQL Server
The MySQL Server is responsible for managing MySQL Databases.
It performs operations such as:
- Creating Databases
- Creating tables
- Storing records
- Retrieving records
- Updating records
- Deleting records
- Managing users
- Controlling permissions
- Processing SQL statements
Client │ │ SQL Request ▼ MySQL Server │ ▼ Database │ ▼ Result │ ▼ Client
MySQL Client
A MySQL Client is a program used to communicate with the MySQL Server.
For example, the MySQL command-line client allows us to type SQL commands directly.
User │ ▼ MySQL Client │ ▼ MySQL Server │ ▼ Database
Later, our Python program will also act as a client of the MySQL Server.
Opening MySQL from Command Line
After MySQL Server and the client tools are installed, we can connect to MySQL from the command line.
A common command is:
mysql -u root -p
Here:
| Part | Meaning |
|---|---|
mysql |
Starts the MySQL command-line client |
-u |
Specifies the username |
root |
Username |
-p |
Requests the password securely |
Login Example
Enter:
mysql -u root -p
MySQL asks for the password:
Enter password:
After successful authentication, the MySQL prompt is displayed:
mysql>
Now SQL and MySQL client commands can be executed.
Command Prompt
│
▼
mysql -u root -p
│
▼
Enter Password
│
▼
Authentication
│
▼
mysql>
MySQL Prompt
After successfully connecting to the MySQL Server, we generally see:
mysql>
For example:
mysql> SHOW DATABASES;
The semicolon ; is normally used to terminate an SQL statement.
Default MySQL Databases
A MySQL Server installation contains system Databases used internally for administration, metadata and other Server functionality.
Common system Databases include:
information_schema mysql performance_schema sys
The exact Databases visible on a particular installation can vary according to the MySQL version, configuration and any Databases already created by the user.
information_schema Database
information_schema provides metadata about the Databases and objects available on the MySQL Server.
Metadata means data about data.
It can provide information about:
- Databases
- Tables
- Columns
- Constraints
- Privileges
- Other Database objects
information_schema
│
▼
Information about
Databases and Objects
mysql Database
The mysql Database is an important system Database.
It stores information used by the MySQL Server for areas such as:
- User accounts
- Privileges
- Authentication-related information
- Server-related system information
It should not be treated like an ordinary application Database.
performance_schema Database
The performance_schema Database provides information used to monitor MySQL Server execution and performance.
It can help inspect different Server activities and performance-related events.
MySQL Server
│
▼
Performance Information
│
▼
performance_schema
sys Database
The sys schema provides convenient views and other objects that make performance and diagnostic information easier to understand.
It works with information available from MySQL's internal metadata and performance facilities.
Display Available Databases
To display the Databases available to the current MySQL account, use:
SHOW DATABASES;
Example:
mysql> SHOW DATABASES;
The output may look similar to:
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+
Additional user-created Databases may also appear.
SHOW DATABASES Command
Syntax
SHOW DATABASES;
This command displays the Databases that the current user is permitted to see.
SHOW DATABASES;
│
▼
MySQL Server
│
▼
Available Databases
Create a New Database
A new Database can be created using the CREATE DATABASE statement.
Syntax
CREATE DATABASE database_name;
Example:
CREATE DATABASE employee_db;
After successful execution, the Database employee_db is created.
Verify the Newly Created Database
After creating the Database, execute:
SHOW DATABASES;
Now the output may include:
+--------------------+ | Database | +--------------------+ | employee_db | | information_schema | | mysql | | performance_schema | | sys | +--------------------+
Select a Database using USE
Before creating or working with tables, we normally select the required Database.
Syntax
USE database_name;
Example:
USE employee_db;
After this command, employee_db becomes the default Database for statements that do not explicitly specify another Database.
MySQL Server
│
▼
USE employee_db;
│
▼
employee_db Selected
Check Current Database
We can check the currently selected Database using:
SELECT DATABASE();
Example:
mysql> SELECT DATABASE();
If employee_db is selected, the result will be similar to:
+------------+ | DATABASE() | +------------+ | employee_db| +------------+
If no default Database has been selected, DATABASE() can return NULL.
Create Employees Table
After selecting employee_db, we can create an employees table.
CREATE TABLE employees(
eno INT,
ename VARCHAR(20),
esal DOUBLE,
eaddr VARCHAR(20)
);
The table contains four columns:
| Column | Data Type | Purpose |
|---|---|---|
eno |
INT |
Employee Number |
ename |
VARCHAR(20) |
Employee Name |
esal |
DOUBLE |
Employee Salary |
eaddr |
VARCHAR(20) |
Employee Address |
Understanding MySQL Data Types
Different columns can store different types of values.
| Data Type | Purpose | Example |
|---|---|---|
INT |
Integer numbers | 100 |
VARCHAR(n) |
Variable-length text | Sachin |
DOUBLE |
Floating-point numeric values | 50000.50 |
DATE |
Date values | 2026-07-25 |
Display Tables
To display tables in the currently selected Database, use:
SHOW TABLES;
Example:
mysql> SHOW TABLES;
If employees exists, the output will be similar to:
+-----------------------+ | Tables_in_employee_db | +-----------------------+ | employees | +-----------------------+
View Table Structure using DESC
To view the structure of a table, we can use:
DESC employees;
or:
DESCRIBE employees;
The output displays information such as:
- Column names
- Data types
- Whether NULL is allowed
- Key information
- Default values
- Extra attributes
Example output:
+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | eno | int | YES | | NULL | | | ename | varchar(20) | YES | | NULL | | | esal | double | YES | | NULL | | | eaddr | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+
Insert Employee Record
Records can be inserted using the SQL INSERT statement.
Example:
INSERT INTO employees VALUES (100, 'Sachin', 50000, 'Mumbai');
Another example:
INSERT INTO employees VALUES (200, 'Dhoni', 60000, 'Ranchi');
Another example:
INSERT INTO employees VALUES (300, 'Kohli', 70000, 'Delhi');
Now the table contains three employee records.
Retrieve Employee Records
To retrieve all employee records, use:
SELECT * FROM employees;
Example output:
+------+--------+-------+--------+ | eno | ename | esal | eaddr | +------+--------+-------+--------+ | 100 | Sachin | 50000 | Mumbai | | 200 | Dhoni | 60000 | Ranchi | | 300 | Kohli | 70000 | Delhi | +------+--------+-------+--------+
Here:
SELECTretrieves data.*means all columns.FROM employeesspecifies the source table.
Select Specific Columns
We do not always have to retrieve every column.
For example:
SELECT eno, ename FROM employees;
This retrieves only the employee number and employee name.
+------+--------+ | eno | ename | +------+--------+ | 100 | Sachin | | 200 | Dhoni | | 300 | Kohli | +------+--------+
Filtering Records using WHERE
The WHERE clause can be used to retrieve records that satisfy a condition.
Example:
SELECT * FROM employees WHERE eno = 100;
Output:
+------+--------+-------+--------+ | eno | ename | esal | eaddr | +------+--------+-------+--------+ | 100 | Sachin | 50000 | Mumbai | +------+--------+-------+--------+
Update Employee Data
Existing data can be modified using the UPDATE statement.
Example:
UPDATE employees SET esal = 55000 WHERE eno = 100;
This changes the salary of employee number 100.
Before
esal = 50000
│
▼
UPDATE
│
▼
After
esal = 55000
Delete Employee Record
The DELETE statement removes records from a table.
Example:
DELETE FROM employees WHERE eno = 300;
This removes the employee whose employee number is 300.
The WHERE condition is very important because:
DELETE FROM employees;
without a WHERE clause attempts to delete all rows from the table.
Drop Employees Table
To remove the complete table definition and its data, use:
DROP TABLE employees;
This is different from DELETE.
| DELETE | DROP TABLE |
|---|---|
| Deletes rows | Removes the table itself |
| Table remains | Table definition is removed |
| Can use WHERE | Does not use WHERE to remove individual rows |
Drop a Database
A complete Database can be removed using:
DROP DATABASE database_name;
Example:
DROP DATABASE employee_db;
This removes the Database and its objects.
Important: DROP DATABASE is destructive and should be used carefully.
MySQL Command Categories
SQL commands are commonly grouped according to their purpose.
| Category | Meaning | Examples |
|---|---|---|
| DDL | Data Definition Language | CREATE, ALTER, DROP, TRUNCATE |
| DML | Data Manipulation Language | INSERT, UPDATE, DELETE |
| DQL | Data Query Language | SELECT |
| DCL | Data Control Language | GRANT, REVOKE |
| TCL | Transaction Control Language | COMMIT, ROLLBACK, SAVEPOINT |
DDL Commands
DDL stands for Data Definition Language.
DDL commands are used to define or modify Database structures.
Important commands include:
CREATE ALTER DROP TRUNCATE
Examples:
CREATE DATABASE employee_db;
CREATE TABLE employees(
eno INT,
ename VARCHAR(20)
);
DROP TABLE employees;
DML Commands
DML stands for Data Manipulation Language.
DML commands are used to manipulate table records.
Important commands include:
INSERT UPDATE DELETE
Examples:
INSERT INTO employees VALUES (100, 'Sachin', 50000, 'Mumbai'); UPDATE employees SET esal = 55000 WHERE eno = 100; DELETE FROM employees WHERE eno = 100;
DQL Command
DQL stands for Data Query Language.
The main command is:
SELECT
Example:
SELECT * FROM employees;
It retrieves data from the table.
TCL Commands
TCL stands for Transaction Control Language.
Important TCL commands include:
COMMIT ROLLBACK SAVEPOINT
COMMIT makes transaction changes permanent.
ROLLBACK can cancel applicable uncommitted transaction changes.
DCL Commands
DCL stands for Data Control Language.
DCL is mainly related to Database permissions.
Important commands include:
GRANT REVOKE
GRANT gives privileges.
REVOKE removes previously granted privileges.
Important MySQL Commands
| Command | Purpose |
|---|---|
SHOW DATABASES; |
Display available Databases |
CREATE DATABASE db; |
Create a Database |
USE db; |
Select a default Database |
SELECT DATABASE(); |
Show the current default Database |
SHOW TABLES; |
Display tables in the selected Database |
DESC table; |
Display table structure |
CREATE TABLE |
Create a table |
INSERT INTO |
Insert records |
SELECT |
Retrieve records |
UPDATE |
Modify records |
DELETE |
Delete records |
DROP TABLE |
Remove a table |
DROP DATABASE |
Remove a Database |
Complete MySQL Command-Line Demo
The following sequence demonstrates the basic MySQL workflow:
mysql -u root -p
After successful login:
SHOW DATABASES;
CREATE DATABASE employee_db;
SHOW DATABASES;
USE employee_db;
SELECT DATABASE();
CREATE TABLE employees(
eno INT,
ename VARCHAR(20),
esal DOUBLE,
eaddr VARCHAR(20)
);
SHOW TABLES;
DESC employees;
INSERT INTO employees
VALUES (100, 'Sachin', 50000, 'Mumbai');
INSERT INTO employees
VALUES (200, 'Dhoni', 60000, 'Ranchi');
INSERT INTO employees
VALUES (300, 'Kohli', 70000, 'Delhi');
SELECT * FROM employees;
Complete Demo Output
After inserting the records:
SELECT * FROM employees;
The output will be similar to:
+------+--------+-------+--------+ | eno | ename | esal | eaddr | +------+--------+-------+--------+ | 100 | Sachin | 50000 | Mumbai | | 200 | Dhoni | 60000 | Ranchi | | 300 | Kohli | 70000 | Delhi | +------+--------+-------+--------+
Complete Execution Flow
START
│
▼
Start MySQL Server
│
▼
Open MySQL Client
│
▼
mysql -u root -p
│
▼
Enter Password
│
▼
Successful Login
│
▼
SHOW DATABASES
│
▼
CREATE DATABASE employee_db
│
▼
USE employee_db
│
▼
CREATE TABLE employees
│
▼
SHOW TABLES
│
▼
DESC employees
│
▼
INSERT Employee Data
│
▼
SELECT * FROM employees
│
▼
Display Employee Data
│
▼
END
MySQL vs Oracle Database
Both MySQL and Oracle Database are relational Database systems, but they are separate products with different ecosystems and features.
| MySQL | Oracle Database |
|---|---|
| Relational Database system | Relational Database system |
| Owned and developed by Oracle Corporation | Developed by Oracle Corporation |
| Has open-source Community Edition and commercial editions | Primarily commercial, with certain free editions available |
| Commonly used for web and general-purpose applications | Commonly used in enterprise Database environments |
| Uses SQL with MySQL-specific features | Uses SQL with Oracle-specific features |
| Can be accessed from Python | Can be accessed from Python |
From MySQL Command Line to Python
At this stage, we are learning MySQL commands directly.
After understanding these commands, we can execute similar Database operations from Python.
Current Stage User │ ▼ MySQL Client │ ▼ MySQL Server Next Stage Python Program │ ▼ MySQL Driver │ ▼ MySQL Server │ ▼ Database
A Python MySQL driver provides the connection between Python and MySQL.
Important Notes
- MySQL is a Relational Database Management System.
- MySQL uses SQL for Database operations.
- SQL is a language, whereas MySQL is Database software.
- MySQL follows a client-server architecture.
- The MySQL Server manages Databases and processes requests.
- The MySQL command-line client can be used to communicate with the Server.
mysql -u root -pis commonly used to connect using therootaccount.SHOW DATABASES;displays Databases visible to the current account.- Common MySQL system Databases include
information_schema,mysql,performance_schemaandsys. CREATE DATABASEcreates a new Database.USEselects a default Database.SELECT DATABASE()displays the currently selected default Database.SHOW TABLES;displays tables in the selected Database.DESCorDESCRIBEdisplays table structure.CREATE TABLEcreates a table.INSERTadds records.SELECTretrieves records.UPDATEmodifies records.DELETEremoves records.DROP TABLEremoves the table definition and its data.DROP DATABASEremoves a Database and its objects.- Be careful when executing destructive commands such as
DELETE,DROP TABLEandDROP DATABASE. - Python can communicate with MySQL using an appropriate MySQL Database driver.
Summary
| Topic | Description |
|---|---|
| Database | MySQL |
| Type | RDBMS |
| Query Language | SQL |
| Architecture | Client-Server |
| Common System Databases | information_schema, mysql, performance_schema, sys |
| Display Databases | SHOW DATABASES; |
| Create Database | CREATE DATABASE |
| Select Database | USE |
| Current Database | SELECT DATABASE(); |
| Display Tables | SHOW TABLES; |
| Table Structure | DESC / DESCRIBE |
| Create Table | CREATE TABLE |
| Insert Data | INSERT |
| Retrieve Data | SELECT |
| Modify Data | UPDATE |
| Delete Data | DELETE |
| Remove Table | DROP TABLE |
| Remove Database | DROP DATABASE |
Quick Revision
MySQL
│
├── RDBMS
│
├── Uses SQL
│
├── Client-Server Architecture
│
└── Stores Data in Tables
│
▼
SHOW DATABASES;
│
▼
CREATE DATABASE employee_db;
│
▼
USE employee_db;
│
▼
CREATE TABLE employees(...);
│
▼
SHOW TABLES;
│
▼
DESC employees;
│
▼
INSERT INTO employees ...
│
▼
SELECT * FROM employees;
Part 15 - Final Concept
MySQL
│
▼
RDBMS
│
┌───────────┴───────────┐
│ │
▼ ▼
MySQL Client MySQL Server
│
▼
Databases
│
▼
Tables
│
▼
Rows
│
▼
Columns
Basic Workflow
│
▼
mysql -u root -p
│
▼
SHOW DATABASES;
│
▼
CREATE DATABASE employee_db;
│
▼
USE employee_db;
│
▼
CREATE TABLE employees(...);
│
▼
SHOW TABLES;
│
▼
DESC employees;
│
▼
INSERT INTO employees ...
│
▼
SELECT * FROM employees;
Part 15 Completed
In this part, we learned the basic concepts of MySQL, its important features, client-server architecture, common system Databases and the essential MySQL commands required before connecting MySQL with Python.
Next: Part 16 — Python MySQL Database Connectivity: Driver, Installation & Testing
Introduction
In the previous part, we learned the basic concepts of MySQL Database, its features, system Databases and important MySQL commands.
Now we will learn how a Python program communicates with MySQL Database.
Python cannot communicate with MySQL Database directly. We need suitable Database driver or connector software between Python and MySQL.
In this part, we will understand:
- What is a Database Driver?
- Why is a MySQL Driver required?
- What is a MySQL Connector?
- Python to MySQL architecture
- Different MySQL drivers available for Python
- MySQL Connector/Python
- Installing MySQL Connector/Python
- Installing using
pip - Testing the installation
- Importing
mysql.connector - Finding the installed package
- What is PATH?
- Why PATH is required?
- How to check PATH?
- What is PYTHONPATH?
- Difference between PATH and PYTHONPATH
- Common installation problems
- Testing Python-MySQL setup
Python Program
│
▼
MySQL Driver / Connector
│
▼
MySQL Server
│
▼
Database
│
▼
Tables
What is a Database Driver?
A Database Driver is software that allows an application to communicate with a Database Management System.
Simple Definition
Database Driver = Software that provides communication between an application and a Database.
For example:
Python Application
│
│ Database Request
▼
Database Driver
│
▼
Database Server
The driver understands the communication requirements of the Database and provides Python APIs for performing Database operations.
Why is a MySQL Driver Required?
Suppose we write a Python program and want to retrieve employee information from MySQL.
Python needs a library that knows how to:
- Connect to the MySQL Server
- Authenticate the Database user
- Send SQL statements
- Receive query results
- Handle transactions
- Handle Database errors
- Close Database connections
This work is performed through the MySQL driver or connector.
Without Driver Python ─────X─────► MySQL With Driver Python │ ▼ MySQL Driver │ ▼ MySQL Server
What is a Connector?
A connector is a software component that enables an application to establish communication with a Database system.
In Python MySQL programming, the terms driver and connector are often used when discussing the library that provides Database connectivity.
Python │ ▼ Connector │ ▼ MySQL
Once the connector is installed, Python can import its modules and use the provided API.
Python to MySQL Architecture
The basic architecture of Python MySQL Database programming is:
Python Application
│
▼
Python DB API /
Connector API
│
▼
MySQL Connector
│
▼
MySQL Server
│
▼
Database
│
▼
Table
The Python program sends SQL commands through the connector.
The connector communicates with the MySQL Server and returns the result to the Python application.
MySQL Drivers Available for Python
Several libraries can be used to communicate with MySQL from Python.
Examples include:
mysql-connector-pythonPyMySQLmysqlclient
In this tutorial, we will use:
mysql-connector-python
It provides the:
mysql.connector
Python module used in our programs.
What is MySQL Connector/Python?
MySQL Connector/Python is a Python driver for communicating with MySQL Database servers.
After installing it, we can write:
import mysql.connector
and create a MySQL Database connection from Python.
Python Program
│
▼
import mysql.connector
│
▼
MySQL Connector/Python
│
▼
MySQL Server
Package Name vs Import Name
One important point is that the package name used during installation and the module name used inside Python are different.
| Purpose | Name |
|---|---|
| Package installation | mysql-connector-python |
| Python import | mysql.connector |
Installation:
python -m pip install mysql-connector-python
Import:
import mysql.connector
Do not confuse these two names.
Before Installing the Connector
Before installing MySQL Connector/Python, verify that Python and pip are available.
Check Python:
python --version
Depending on the system, you may also use:
py --version
or:
python3 --version
Check pip:
python -m pip --version
If Python and pip are configured correctly, their version information will be displayed.
Installing MySQL Connector/Python
The connector can be installed from the Python Package Index using pip.
Recommended Command
python -m pip install mysql-connector-python
On systems where the Python launcher is used:
py -m pip install mysql-connector-python
On some Linux/macOS environments:
python3 -m pip install mysql-connector-python
The command downloads and installs the connector into the Python environment associated with that interpreter.
Installation using pip
A commonly seen command is:
pip install mysql-connector-python
This can work when the pip command points to the intended Python installation.
However, the following form is generally clearer:
python -m pip install mysql-connector-python
because it explicitly runs pip through the selected Python interpreter.
python │ ▼ -m pip │ ▼ install │ ▼ mysql-connector-python
Installation Flow
START
│
▼
Verify Python
│
▼
python --version
│
▼
Verify pip
│
▼
python -m pip --version
│
▼
Install MySQL Connector
│
▼
python -m pip install mysql-connector-python
│
▼
Package Installed
│
▼
Test Python Import
│
▼
import mysql.connector
│
▼
END
Possible Installation Output
During installation, output may look similar to:
Collecting mysql-connector-python Downloading mysql_connector_python-... Installing collected packages: mysql-connector-python Successfully installed mysql-connector-python-...
The exact version number and messages depend on the Python environment and connector version being installed.
The important message is similar to:
Successfully installed mysql-connector-python
Verify Connector Installation using pip
After installation, we can inspect the package using:
python -m pip show mysql-connector-python
The command displays information such as:
Name: mysql-connector-python Version: ... Location: ...
The Location field indicates where the package is installed.
Display Installed Packages
We can also display installed Python packages using:
python -m pip list
Look for:
mysql-connector-python
If it appears in the package list, the package is installed in that Python environment.
Testing MySQL Connector Installation
The simplest test is to import the module.
Test Program
import mysql.connector
print("MySQL Connector imported successfully")
If the import succeeds, the output will be:
MySQL Connector imported successfully
If the connector is unavailable in the current Python environment, Python may report an import error such as:
ModuleNotFoundError: No module named 'mysql'
Check Connector Version
We can also inspect the imported connector version.
import mysql.connector print(mysql.connector.__version__)
The output depends on the installed version.
For example:
9.x.x
The exact number can differ from system to system.
Complete Connector Test Program
main.py
No output captured.
Program Explanation
The first statement:
import mysql.connector
asks Python to locate and load the mysql.connector module.
If the module is found successfully, execution continues.
Then:
print("MySQL Connector imported successfully")
displays the confirmation message.
Finally:
print("Connector Version:", mysql.connector.__version__)
displays the installed connector version.
Execution Flow of Connector Test
START
│
▼
Start Python Program
│
▼
import mysql.connector
│
┌───────┴────────┐
│ │
Found Not Found
│ │
▼ ▼
Import Successful Import Error
│
▼
Display Confirmation
│
▼
Display Version
│
▼
END
Finding the Installed Module
We can inspect where the imported module is located using:
import mysql.connector print(mysql.connector.__file__)
The output may point to a location similar to:
.../site-packages/mysql/connector/__init__.py
The exact location depends on:
- Operating system
- Python installation
- Virtual environment
- Python version
- User-level or system-level installation
What is site-packages?
site-packages is a common directory where third-party Python packages are installed.
When we install:
python -m pip install mysql-connector-python
the connector is normally installed into a package location associated with that Python environment.
Python Environment
│
▼
site-packages
│
▼
mysql
│
▼
connector
Python's import system can then locate the installed module.
What is PATH?
PATH is an operating-system environment variable.
It contains a list of directories that the operating system searches when we type executable commands.
Simple Definition
PATH = Directories searched by the operating system for executable commands.
For example, when we type:
python
the operating system may search directories listed in PATH to locate the Python executable.
Command │ ▼ python │ ▼ Search PATH │ ▼ Find python.exe / Python executable │ ▼ Start Python
Why is PATH Important?
If Python's executable directory is available through PATH, we can execute Python from a terminal without specifying its complete location.
For example:
python --version
Similarly, command-line scripts installed by Python packages are often placed in a Scripts or bin directory.
That directory may also need to be accessible through PATH if we want to execute those commands directly.
Example of PATH
On Windows, Python-related PATH entries may look similar to:
C:\Users\User\AppData\Local\Programs\Python\Python3xx\ C:\Users\User\AppData\Local\Programs\Python\Python3xx\Scripts\
The exact directories depend on how and where Python was installed.
Do not copy a path blindly. Always use the actual Python installation directories on your computer.
Checking PATH on Windows
In Command Prompt, we can display the current PATH using:
echo %PATH%
We can also locate the Python command using:
where python
and locate pip using:
where pip
These commands are useful when multiple Python installations exist.
Checking PATH on Linux or macOS
On Linux or macOS, the PATH value can commonly be displayed using:
echo $PATH
To locate Python:
which python3
To locate pip:
which pip3
The exact commands available can vary according to the shell and system configuration.
Python is Not Recognized
On Windows, if Python is not configured correctly, a command such as:
python --version
may fail because the operating system cannot locate the intended Python executable.
Possible solutions include:
- Verify that Python is installed.
- Use the Python launcher with
pyif available. - Add the correct Python installation directory to PATH.
- Re-run the Python installer and enable its PATH-related option where appropriate.
- Open a new terminal after changing environment variables.
pip is Not Recognized
If:
pip --version
does not work, first try:
python -m pip --version
or on Windows:
py -m pip --version
This is often preferable to manually changing PATH only to use the standalone pip command.
If Python itself is not found, then the Python installation or PATH configuration should be checked.
What is PYTHONPATH?
PYTHONPATH is an optional environment variable that can add directories to Python's module search path.
Simple Definition
PYTHONPATH = Optional directories added to Python's module search path.
When Python executes:
import some_module
it searches locations available through its import system, including entries in sys.path.
If PYTHONPATH is configured, its directories can be added to that search path.
How Python Searches for Modules
When Python sees:
import mysql.connector
it uses its import system to locate the required package.
A simplified view is:
import mysql.connector
│
▼
Python Import System
│
▼
Search sys.path
│
├── Script / environment-related locations
├── Standard Library locations
├── site-packages
└── Additional configured locations
│
▼
Find mysql.connector
│
▼
Import Module
Normally, a package installed correctly with pip into the active Python environment is available through that environment's site-packages.
Checking Python Module Search Path
Python's current module search path can be inspected using sys.path.
import sys
for path in sys.path:
print(path)
This displays the directories Python currently considers when importing modules.
It is especially useful when diagnosing import problems.
Checking PYTHONPATH
On Windows Command Prompt:
echo %PYTHONPATH%
On Linux/macOS:
echo $PYTHONPATH
If no explicit PYTHONPATH has been configured, the variable may be empty or undefined.
This is completely normal for many Python installations.
Do We Need PYTHONPATH for mysql.connector?
Normally, no manual PYTHONPATH configuration is required when MySQL Connector/Python is installed correctly into the Python environment being used.
For example:
python -m pip install mysql-connector-python
installs the package into the environment associated with that Python interpreter.
Then:
import mysql.connector
should normally work without manually setting PYTHONPATH.
Manual PYTHONPATH configuration is more relevant when Python needs to search additional custom module directories.
PATH vs PYTHONPATH
| Feature | PATH | PYTHONPATH |
|---|---|---|
| Used By | Operating system / shell | Python import system |
| Main Purpose | Locate executable commands | Add module-search directories |
| Example | Finding python |
Helping Python locate custom modules |
| Related To | Commands and executables | Python imports |
| Usually Needed Manually for Connector? | Only as required for command access | Normally no |
PATH vs sys.path
PATH and sys.path are also different concepts.
PATH │ ▼ Operating System Searches for Executables sys.path │ ▼ Python Searches for Importable Modules
Example:
python app.py
The operating system may use PATH to locate python.
Inside app.py:
import mysql.connector
Python uses its import search path, represented by sys.path, to locate the module.
Common Problem — ModuleNotFoundError
Suppose we execute:
import mysql.connector
and receive:
ModuleNotFoundError: No module named 'mysql'
This usually means that the required package is not available to the Python interpreter running the program.
Possible reasons include:
- The connector is not installed.
- The connector was installed for a different Python installation.
- A different virtual environment is active.
- The IDE is using another Python interpreter.
- The installation did not complete successfully.
Solution for ModuleNotFoundError
First check which Python interpreter is being used:
python --version
Then check whether the package exists for that interpreter:
python -m pip show mysql-connector-python
If it is not installed, execute:
python -m pip install mysql-connector-python
Then test:
python -c "import mysql.connector; print(mysql.connector.__version__)"
If this succeeds but the code still fails inside an IDE, verify that the IDE is using the same Python interpreter.
Common Problem — Multiple Python Installations
A computer may contain multiple Python installations.
For example:
Python A │ └── mysql-connector-python installed Python B │ └── Connector not installed
If the program runs with Python B, then:
import mysql.connector
can fail even though the package was installed for Python A.
This is why commands such as:
python -m pip install mysql-connector-python
are useful. They help associate the package installation with the Python interpreter being invoked.
Check Which Python is Being Used
From inside Python, we can display the interpreter path:
import sys print(sys.executable)
Example output on Windows may look similar to:
C:\Users\User\AppData\Local\Programs\Python\Python3xx\python.exe
This tells us exactly which Python executable is running the program.
Complete Environment Diagnostic Program
main.py
No output captured.
Diagnostic Program Explanation
The diagnostic program provides useful information about the current Python environment.
| Statement | Purpose |
|---|---|
sys.executable |
Displays the current Python executable |
sys.version |
Displays Python version information |
mysql.connector.__version__ |
Displays Connector version |
mysql.connector.__file__ |
Displays Connector module location |
sys.path |
Displays Python module search paths |
Using a Virtual Environment
Python projects are often created inside a virtual environment.
A virtual environment provides an isolated Python package environment for a project.
Project
│
▼
Virtual Environment
│
├── Python
├── pip
└── Project Packages
│
▼
mysql-connector-python
If a virtual environment is being used, install the connector into that environment.
Create and Activate Virtual Environment
Create a virtual environment:
python -m venv venv
On Windows Command Prompt, activation commonly uses:
venv\Scripts\activate
On Windows PowerShell, activation commonly uses:
.\venv\Scripts\Activate.ps1
On Linux/macOS:
source venv/bin/activate
After activation, install the connector:
python -m pip install mysql-connector-python
Virtual Environment Installation Flow
Create Project
│
▼
python -m venv venv
│
▼
Activate venv
│
▼
python -m pip install
mysql-connector-python
│
▼
Connector Installed
Inside venv
│
▼
Run Python Program
│
▼
import mysql.connector
Connector Installation vs MySQL Server Installation
Installing MySQL Connector/Python is different from installing MySQL Server.
| MySQL Server | MySQL Connector/Python |
|---|---|
| Runs and manages MySQL Databases | Allows Python to communicate with MySQL |
| Stores Database data | Provides Python connectivity APIs |
| Database Server software | Python package |
Installing:
python -m pip install mysql-connector-python
does not install the MySQL Database Server itself.
Test MySQL Server Separately
The connector can import successfully even if the MySQL Server is currently stopped.
These are two different tests:
Test 1 ------ import mysql.connector Checks: Is the Python connector available? Test 2 ------ mysql.connector.connect(...) Checks: Can Python connect to a MySQL Server?
Therefore, successful import confirms the connector installation, but it does not by itself confirm that a Database connection can be established.
First Connection Test
After the connector is installed and the MySQL Server is running, we can perform a basic connection test.
import mysql.connector
con = mysql.connector.connect(
host="localhost",
user="root",
password="your_password"
)
print("Connection established successfully")
con.close()
Replace:
your_password
with the password configured for the MySQL account being used.
Connection Parameters
The connection function receives Database connection information.
mysql.connector.connect(
host="localhost",
user="root",
password="your_password"
)
| Parameter | Purpose |
|---|---|
host |
MySQL Server hostname or address |
user |
MySQL username |
password |
Password for the MySQL account |
For a local MySQL Server:
host="localhost"
is commonly used.
Complete Connection Test Program
main.py
No output captured.
Connection Test Program Explanation
The program imports:
import mysql.connector
Then:
mysql.connector.connect(...)
attempts to establish a connection with the MySQL Server.
The statement:
con.is_connected()
checks whether the Connection object reports an active connection.
Database-related connector errors are handled using:
except mysql.connector.Error as e:
Finally, the connection is closed using:
con.close()
Connection Test Execution Flow
START
│
▼
import mysql.connector
│
▼
mysql.connector.connect()
│
┌────────┴────────┐
│ │
Success Error
│ │
▼ ▼
Connection Object except Block
│ │
▼ │
con.is_connected() │
│ │
▼ │
Display Success Message │
│ │
└────────┬────────┘
▼
finally
│
▼
Close Connection
│
▼
END
Common Connection Problems
Even after the connector is installed correctly, Database connection errors can occur.
Common reasons include:
- MySQL Server is not running.
- Incorrect username.
- Incorrect password.
- Incorrect hostname.
- Incorrect port.
- User does not have required privileges.
- Server is not accepting the requested connection.
- Network or firewall configuration prevents access to a remote Server.
These are connection problems, not necessarily connector installation problems.
Installation Problem vs Connection Problem
| Problem | Likely Area |
|---|---|
ModuleNotFoundError |
Python package/environment problem |
python command not found |
Python installation/PATH problem |
pip command not found |
pip command/PATH/environment problem |
| Access denied | MySQL authentication/privilege problem |
| Cannot connect to MySQL Server | Server/network/configuration problem |
Identifying the type of problem helps us apply the correct solution.
Recommended Setup Verification
Use the following sequence to verify the Python-MySQL environment.
Step 1 — Check Python
python --version
Step 2 — Check pip
python -m pip --version
Step 3 — Install Connector
python -m pip install mysql-connector-python
Step 4 — Verify Package
python -m pip show mysql-connector-python
Step 5 — Test Import
python -c "import mysql.connector; print(mysql.connector.__version__)"
Step 6 — Verify MySQL Server
mysql -u root -p
Step 7 — Test Connection from Python
mysql.connector.connect(...)
Complete Setup Flow
Python Installed?
│
┌────┴────┐
│ │
Yes No
│ │
▼ ▼
Check pip Install Python
│
▼
Install mysql-connector-python
│
▼
Test import mysql.connector
│
┌────┴────┐
│ │
Success Failure
│ │
│ ▼
│ Check Interpreter
│ and Installation
│
▼
Check MySQL Server
│
▼
Test Credentials
│
▼
mysql.connector.connect()
│
┌────┴────┐
│ │
Success Error
│ │
▼ ▼
Ready for Diagnose Server /
DB Programs Credentials / Network
Important Commands
| Command | Purpose |
|---|---|
python --version |
Check Python version |
python -m pip --version |
Check pip |
python -m pip install mysql-connector-python |
Install MySQL Connector/Python |
python -m pip show mysql-connector-python |
Show connector package information |
python -m pip list |
Display installed Python packages |
where python |
Locate Python on Windows |
where pip |
Locate pip on Windows |
which python3 |
Locate Python on many Linux/macOS systems |
echo %PATH% |
Display PATH in Windows Command Prompt |
echo $PATH |
Display PATH in common Linux/macOS shells |
echo %PYTHONPATH% |
Display PYTHONPATH in Windows Command Prompt |
echo $PYTHONPATH |
Display PYTHONPATH in common Linux/macOS shells |
Important Notes
- Python requires an appropriate driver or connector to communicate with MySQL.
- In this tutorial, we use
mysql-connector-python. - The installation package name is
mysql-connector-python. - The Python import is
import mysql.connector. - A recommended installation form is
python -m pip install mysql-connector-python. python -m piphelps ensure that pip runs with the selected Python interpreter.python -m pip show mysql-connector-pythoncan be used to inspect the installed package.mysql.connector.__version__can display the imported connector version.mysql.connector.__file__can display the module's location.PATHis mainly used by the operating system to locate executable commands.PYTHONPATHcan add directories to Python's module search path.PATHandPYTHONPATHare different.sys.pathshows Python's current module search paths.- Normally, we do not need to manually configure
PYTHONPATHfor a package correctly installed into the active Python environment. - If
mysql.connectorcannot be imported, verify the Python interpreter and package installation before manually modifying environment variables. - Multiple Python installations are a common reason for package import problems.
- An IDE may use a different Python interpreter from the terminal.
- A virtual environment has its own package environment.
- Installing MySQL Connector/Python does not install MySQL Server.
- Successful
import mysql.connectorverifies the Python connector installation, not the MySQL Server connection. - A successful Database connection additionally requires a running MySQL Server and valid connection details.
Summary
| Topic | Description |
|---|---|
| Database | MySQL |
| Python Driver | MySQL Connector/Python |
| Package Name | mysql-connector-python |
| Import | import mysql.connector |
| Installation | python -m pip install mysql-connector-python |
| Package Information | python -m pip show mysql-connector-python |
| Version | mysql.connector.__version__ |
| Module Location | mysql.connector.__file__ |
| PATH | Used to locate executable commands |
| PYTHONPATH | Optional additional Python module-search directories |
| Python Search Path | sys.path |
| Python Executable | sys.executable |
| Connection Function | mysql.connector.connect() |
| Connector Error | mysql.connector.Error |
Quick Revision
Python │ ▼ Needs MySQL Driver │ ▼ mysql-connector-python │ ▼ Install │ ▼ python -m pip install mysql-connector-python │ ▼ Test │ ▼ import mysql.connector │ ▼ Connector Available │ ▼ mysql.connector.connect() │ ▼ MySQL Server PATH │ ▼ Find Executable Commands PYTHONPATH │ ▼ Add Python Module Search Directories sys.path │ ▼ Current Python Import Search Path
Part 16 - Final Concept
Python Program
│
▼
import mysql.connector
│
▼
MySQL Connector/Python
│
▼
MySQL Connection
│
▼
MySQL Server
│
▼
Database
│
▼
Tables
Installation Flow
-----------------
Check Python
│
▼
Check pip
│
▼
python -m pip install
mysql-connector-python
│
▼
Import Test
│
▼
import mysql.connector
│
▼
Connector Ready
Environment Concepts
--------------------
PATH
│
└── Helps OS locate executable commands
PYTHONPATH
│
└── Optionally adds module-search directories
sys.path
│
└── Python's active module search path
Part 16 Completed
In this part, we learned why a MySQL driver is required, how to install mysql-connector-python, how to test the connector, and how PATH, PYTHONPATH, sys.path and Python environments affect Database programming.
We also performed a basic MySQL connection test.
Next: Part 17 — App1: Connect Python with MySQL Database and Print Connection Information
Introduction
In the previous part, we learned how to install and test MySQL Connector/Python.
Now we will use Python to perform actual Database operations on a MySQL Database.
In this application, we will:
- Import
mysql.connector - Connect Python with MySQL
- Create a Cursor object
- Create an
employeestable - Insert employee records
- Use
commit()to save inserted records - Execute a
SELECTquery - Retrieve employee records
- Display employee information
- Handle MySQL errors
- Close the Cursor and Connection
Python Program
│
▼
mysql.connector
│
▼
MySQL Server
│
▼
Database
│
▼
Create employees Table
│
▼
Insert Records
│
▼
commit()
│
▼
SELECT Records
│
▼
Display Employee Data
Application Requirements
Before executing this program, make sure:
- Python is installed.
- MySQL Server is installed and running.
mysql-connector-pythonis installed.- A valid MySQL username and password are available.
- The required Database exists.
For example, we can create a Database:
CREATE DATABASE employee_db;
We will use:
employee_db
as the Database name in this application.
Database and Table Used
The application uses the following structure:
MySQL Server
│
▼
employee_db
│
▼
employees
│
├── eno
├── ename
├── esal
└── eaddr
| Column | Data Type | Purpose |
|---|---|---|
eno |
INT |
Employee Number |
ename |
VARCHAR(20) |
Employee Name |
esal |
DOUBLE |
Employee Salary |
eaddr |
VARCHAR(20) |
Employee Address |
Step 1 — Create Database
Before running the Python program, create the required Database if it does not already exist.
CREATE DATABASE employee_db;
Verify it using:
SHOW DATABASES;
Then:
employee_db
should appear in the available Database list.
Complete Program
main.py
No output captured.
Program Output
If the table is initially empty and the program executes successfully, the output will be similar to:
Employees table created successfully 3 records inserted successfully Employee Information (100, 'Sachin', 50000.0, 'Mumbai') (200, 'Dhoni', 60000.0, 'Ranchi') (300, 'Kohli', 70000.0, 'Delhi') MySQL connection closed
The exact representation of numeric values can vary according to the MySQL data type and connector behaviour.
Note: If you run this same program repeatedly without clearing the table or adding a uniqueness constraint, additional copies of these employee records will be inserted.
Step 2 — Import MySQL Connector
The program starts with:
import mysql.connector
This imports the MySQL Connector/Python module.
It provides functionality for:
- Connecting to MySQL
- Creating Cursor objects
- Executing SQL queries
- Managing transactions
- Fetching query results
- Handling MySQL errors
Python │ ▼ mysql.connector │ ▼ MySQL Server
Step 3 — Establish MySQL Connection
The connection is established using:
con = mysql.connector.connect(
host="localhost",
user="root",
password="your_password",
database="employee_db"
)
The returned Connection object is stored in:
con
| Parameter | Purpose |
|---|---|
host |
Specifies the MySQL Server |
user |
Specifies the MySQL username |
password |
Specifies the MySQL account password |
database |
Specifies the Database to use |
Replace:
your_password
with the password configured for your MySQL account.
Connection Flow
Python Program
│
▼
mysql.connector.connect()
│
├── host
├── user
├── password
└── database
│
▼
MySQL Server
│
▼
employee_db
Step 4 — Create Cursor Object
After establishing the connection, create a Cursor:
cursor = con.cursor()
The Cursor object is used to communicate with MySQL through SQL statements.
Connection
│
▼
con.cursor()
│
▼
Cursor
│
├── execute()
├── executemany()
├── fetchone()
├── fetchmany()
└── fetchall()
Step 5 — Create Employees Table
The table is created using:
cursor.execute("""
CREATE TABLE IF NOT EXISTS employees(
eno INT,
ename VARCHAR(20),
esal DOUBLE,
eaddr VARCHAR(20)
)
""")
The SQL statement is:
CREATE TABLE IF NOT EXISTS employees(
eno INT,
ename VARCHAR(20),
esal DOUBLE,
eaddr VARCHAR(20)
);
IF NOT EXISTS prevents an error when a table with the same name already exists.
Understanding CREATE TABLE
| SQL Part | Meaning |
|---|---|
CREATE TABLE |
Creates a new table |
IF NOT EXISTS |
Create it only when the named table does not already exist |
employees |
Table name |
eno INT |
Employee number |
ename VARCHAR(20) |
Employee name |
esal DOUBLE |
Employee salary |
eaddr VARCHAR(20) |
Employee address |
Table Creation Flow
cursor.execute()
│
▼
CREATE TABLE IF NOT EXISTS employees
│
▼
Does employees Exist?
│
┌──┴──┐
│ │
Yes No
│ │
│ ▼
│ Create Table
│ │
└──┬──┘
▼
Continue Program
Step 6 — Prepare INSERT Query
The INSERT statement is stored in:
sql = """
INSERT INTO employees(eno, ename, esal, eaddr)
VALUES (%s, %s, %s, %s)
"""
The placeholders:
%s
represent values that will be supplied separately through the connector.
There are four placeholders because four column values are inserted.
eno → %s ename → %s esal → %s eaddr → %s
Why Use Placeholders?
Instead of manually building an SQL query by joining values into a string, values should normally be supplied separately through the connector.
For example:
sql = """ INSERT INTO employees(eno, ename, esal, eaddr) VALUES (%s, %s, %s, %s) """
and:
(100, "Sachin", 50000, "Mumbai")
are passed separately.
This is cleaner and avoids treating input values as part of the SQL statement itself.
Step 7 — Employee Records
Multiple employee records are stored in a list:
records = [
(100, "Sachin", 50000, "Mumbai"),
(200, "Dhoni", 60000, "Ranchi"),
(300, "Kohli", 70000, "Delhi")
]
Each tuple represents one employee.
records │ ├── (100, "Sachin", 50000, "Mumbai") │ ├── (200, "Dhoni", 60000, "Ranchi") │ └── (300, "Kohli", 70000, "Delhi")
The tuple values correspond to:
(eno, ename, esal, eaddr)
Step 8 — Insert Multiple Records using executemany()
Multiple employee records are inserted using:
cursor.executemany(sql, records)
executemany() executes the parameterized SQL operation for each parameter set in the supplied sequence.
SQL INSERT
+
records
│
▼
executemany()
│
├── Insert Employee 1
├── Insert Employee 2
└── Insert Employee 3
execute() vs executemany()
| Method | Typical Purpose |
|---|---|
execute() |
Execute one SQL statement with one parameter set |
executemany() |
Execute the same parameterized operation for multiple parameter sets |
For one employee:
cursor.execute(sql, employee)
For multiple employees:
cursor.executemany(sql, records)
Step 9 — Save Records using commit()
After inserting the records, the program executes:
con.commit()
commit() commits the current transaction so the inserted records become permanent.
INSERT Records
│
▼
Pending Transaction Changes
│
▼
con.commit()
│
▼
Changes Committed
This is an important step after transaction-changing operations such as INSERT, UPDATE and DELETE when autocommit is not being used.
What Happens Without commit()?
If a transaction-changing operation is executed but not committed, its changes may remain uncommitted.
If the transaction is later rolled back or the connection ends without committing, those uncommitted changes may not be preserved.
INSERT │ ▼ Uncommitted Changes │ ├── commit() → Save Changes │ └── rollback() → Cancel Applicable Changes
Step 10 — rowcount
After executemany(), the program uses:
print(cursor.rowcount, "records inserted successfully")
cursor.rowcount reports the number of rows affected by the operation according to the connector's result.
For this example, it should normally display:
3 records inserted successfully
Step 11 — Execute SELECT Query
After inserting the records, we retrieve employee information using:
cursor.execute("SELECT * FROM employees")
The SQL query is:
SELECT * FROM employees;
| Part | Meaning |
|---|---|
SELECT |
Retrieve data |
* |
Retrieve all columns |
FROM |
Specifies the source table |
employees |
Employee table |
Step 12 — Retrieve Records using fetchall()
After executing the SELECT query, the program uses:
data = cursor.fetchall()
fetchall() retrieves all remaining rows from the query result.
The result may look conceptually like:
[
(100, 'Sachin', 50000.0, 'Mumbai'),
(200, 'Dhoni', 60000.0, 'Ranchi'),
(300, 'Kohli', 70000.0, 'Delhi')
]
Each employee row is represented as a tuple.
Step 13 — Display Employee Data
The employee records are displayed using:
for row in data:
print(row)
During each iteration, one employee record is assigned to row.
data │ ├── Employee 1 ──► row ──► print() │ ├── Employee 2 ──► row ──► print() │ └── Employee 3 ──► row ──► print()
Output:
(100, 'Sachin', 50000.0, 'Mumbai') (200, 'Dhoni', 60000.0, 'Ranchi') (300, 'Kohli', 70000.0, 'Delhi')
Access Individual Employee Columns
Each row is a tuple, so individual column values can be accessed using indexes.
For example:
row = (100, 'Sachin', 50000.0, 'Mumbai')
| Expression | Column | Example Value |
|---|---|---|
row[0] |
eno | 100 |
row[1] |
ename | Sachin |
row[2] |
esal | 50000.0 |
row[3] |
eaddr | Mumbai |
Program — Display Individual Employee Values
main.py
No output captured.
Output — Individual Employee Values
Employee Number : 100 Employee Name : Sachin Employee Salary : 50000.0 Employee Address : Mumbai Employee Number : 200 Employee Name : Dhoni Employee Salary : 60000.0 Employee Address : Ranchi Employee Number : 300 Employee Name : Kohli Employee Salary : 70000.0 Employee Address : Delhi
Single Record Insert using execute()
If we want to insert only one employee, we can use execute().
Example:
sql = """ INSERT INTO employees(eno, ename, esal, eaddr) VALUES (%s, %s, %s, %s) """ employee = (400, "Rohit", 80000, "Mumbai") cursor.execute(sql, employee) con.commit()
This inserts one employee record.
Complete Single Record Insert Program
main.py
No output captured.
executemany() Example
For multiple records:
records = [
(100, "Sachin", 50000, "Mumbai"),
(200, "Dhoni", 60000, "Ranchi"),
(300, "Kohli", 70000, "Delhi")
]
cursor.executemany(sql, records)
con.commit()
Here, the same INSERT statement is applied to every tuple in records.
Dynamic Insert using Keyboard Input
Employee information can also be collected from the user.
eno = int(input("Enter Employee Number: "))
ename = input("Enter Employee Name: ")
esal = float(input("Enter Employee Salary: "))
eaddr = input("Enter Employee Address: ")
sql = """
INSERT INTO employees(eno, ename, esal, eaddr)
VALUES (%s, %s, %s, %s)
"""
employee = (eno, ename, esal, eaddr)
cursor.execute(sql, employee)
con.commit()
The entered values are supplied separately from the SQL statement.
Complete Dynamic Insert Program
main.py
No output captured.
Dynamic Insert — Sample Execution
Example:
Enter Employee Number: 500 Enter Employee Name: Rahul Enter Employee Salary: 90000 Enter Employee Address: Bangalore 1 record inserted successfully
The resulting record is:
(500, 'Rahul', 90000.0, 'Bangalore')
MySQL Placeholder Syntax
With MySQL Connector/Python, parameterized SQL commonly uses:
%s
Example:
sql = """ INSERT INTO employees VALUES (%s, %s, %s, %s) """ values = (100, "Sachin", 50000, "Mumbai") cursor.execute(sql, values)
Even for numeric values, the placeholder is written as %s.
The connector handles the supplied Python values appropriately.
Do Not Build Queries using String Concatenation
Avoid building SQL statements by directly joining user input into the query.
For example, avoid patterns such as:
query = "INSERT INTO employees VALUES (" + user_input + ")"
Instead, use parameterized queries:
query = """ INSERT INTO employees VALUES (%s, %s, %s, %s) """ cursor.execute(query, values)
Parameterized queries are safer and handle values more reliably.
Exception Handling
MySQL Connector errors can be handled using:
except mysql.connector.Error as e:
The exception object:
e
contains information about the Database error.
Errors can occur because of:
- Incorrect username
- Incorrect password
- MySQL Server not running
- Database does not exist
- Invalid SQL syntax
- Invalid table name
- Constraint violations
- Connection problems
Using rollback() on Transaction Error
When a transaction-changing operation fails, we may roll back uncommitted changes.
Example:
except mysql.connector.Error as e:
if 'con' in locals() and con.is_connected():
con.rollback()
print("MySQL Error:", e)
rollback() cancels applicable uncommitted transaction changes.
INSERT / UPDATE / DELETE
│
▼
Error
│
▼
con.rollback()
│
▼
Cancel Applicable
Uncommitted Changes
Finally Block
The finally block is used to release Database resources.
finally:
if 'cursor' in locals():
cursor.close()
if 'con' in locals() and con.is_connected():
con.close()
The finally block executes whether the main operation succeeds or fails.
try
│
┌──────┴──────┐
│ │
Success Error
│ │
│ except
│ │
└──────┬──────┘
▼
finally
│
▼
Close Resources
Why Check locals()?
Consider:
if 'con' in locals():
This checks whether the variable con was created in the current local scope before trying to use it.
This can be useful when an exception occurs before the connection or Cursor object is successfully created.
Similarly:
if 'cursor' in locals():
checks whether cursor exists before calling:
cursor.close()
Close Cursor
The Cursor is closed using:
cursor.close()
This releases resources associated with the Cursor.
Cursor │ ▼ cursor.close() │ ▼ Cursor Resources Released
Close MySQL Connection
The Connection is closed using:
con.close()
Before closing, the program can check:
con.is_connected()
The connection should be closed after Database operations are completed.
Complete Program with rollback()
main.py
No output captured.
Program Explanation — Complete Sequence
The complete program performs the following operations:
1. Import mysql.connector 2. Connect to MySQL Server 3. Select employee_db 4. Create Cursor 5. Execute CREATE TABLE 6. Prepare INSERT statement 7. Prepare employee records 8. Execute executemany() 9. Execute commit() 10. Execute SELECT query 11. Execute fetchall() 12. Process every employee row 13. Handle errors 14. Close Cursor 15. Close Connection
Complete Execution Flow
START
│
▼
import mysql.connector
│
▼
mysql.connector.connect()
│
▼
Connect employee_db
│
▼
Create Cursor
│
▼
CREATE TABLE IF NOT EXISTS
employees
│
▼
Table Available
│
▼
Prepare INSERT SQL
│
▼
Prepare Employee Records
│
▼
cursor.executemany()
│
▼
Insert 3 Records
│
▼
con.commit()
│
▼
Changes Committed
│
▼
SELECT * FROM employees
│
▼
cursor.fetchall()
│
▼
Employee Data
│
▼
for row in data
│
▼
print(row)
│
▼
More Rows?
/ \
Yes No
│ │
└─ Repeat ▼
finally
│
▼
Close Cursor
│
▼
Close Connection
│
▼
END
Create, Insert and Select Flow
CREATE │ ▼ CREATE TABLE employees │ ▼ Table Created │ ▼ INSERT │ ▼ executemany() │ ▼ Employee Records Inserted │ ▼ COMMIT │ ▼ Records Saved │ ▼ SELECT │ ▼ fetchall() │ ▼ Employee Records Retrieved │ ▼ DISPLAY
Verify Data from MySQL Command Line
After running the Python program, we can verify the records directly from MySQL.
mysql -u root -p
Select the Database:
USE employee_db;
Display tables:
SHOW TABLES;
Check the table structure:
DESC employees;
Display employee records:
SELECT * FROM employees;
Possible MySQL Verification Output
mysql> USE employee_db; Database changed mysql> SHOW TABLES; +-----------------------+ | Tables_in_employee_db | +-----------------------+ | employees | +-----------------------+ mysql> SELECT * FROM employees; +------+--------+---------+--------+ | eno | ename | esal | eaddr | +------+--------+---------+--------+ | 100 | Sachin | 50000.0 | Mumbai | | 200 | Dhoni | 60000.0 | Ranchi | | 300 | Kohli | 70000.0 | Delhi | +------+--------+---------+--------+
Important Issue — Running the Program Multiple Times
The table is created using:
CREATE TABLE IF NOT EXISTS employees(...)
Therefore, if the table already exists, it is not recreated.
However, the INSERT statements still execute every time the program runs.
For example, after the first execution:
100 Sachin 200 Dhoni 300 Kohli
After running the same insertion program again, duplicate rows may be added because the current table definition does not declare eno as unique.
100 Sachin 200 Dhoni 300 Kohli 100 Sachin 200 Dhoni 300 Kohli
Preventing Duplicate Employee Numbers
If each employee number must be unique, we can define eno as a primary key.
CREATE TABLE employees(
eno INT PRIMARY KEY,
ename VARCHAR(20),
esal DOUBLE,
eaddr VARCHAR(20)
);
A primary key uniquely identifies each record.
Then inserting the same eno again causes a duplicate-key error instead of silently creating another employee with the same number.
Improved Employees Table
A better table definition for employee numbers can be:
CREATE TABLE IF NOT EXISTS employees(
eno INT PRIMARY KEY,
ename VARCHAR(20),
esal DOUBLE,
eaddr VARCHAR(20)
);
| Column | Purpose |
|---|---|
eno |
Unique employee identifier |
ename |
Employee name |
esal |
Employee salary |
eaddr |
Employee address |
Methods Used in This Application
| Method / Attribute | Purpose |
|---|---|
mysql.connector.connect() |
Connect to MySQL Server |
con.cursor() |
Create Cursor |
cursor.execute() |
Execute one SQL statement |
cursor.executemany() |
Execute parameterized SQL for multiple parameter sets |
con.commit() |
Commit transaction changes |
con.rollback() |
Roll back applicable uncommitted changes |
cursor.fetchall() |
Retrieve all remaining query rows |
cursor.rowcount |
Report affected row count |
con.is_connected() |
Check connection state |
cursor.close() |
Close Cursor |
con.close() |
Close Connection |
SQL Statements Used
| SQL Statement | Purpose |
|---|---|
CREATE TABLE |
Create employees table |
INSERT INTO |
Insert employee records |
SELECT |
Retrieve employee records |
Important Notes
- Python communicates with MySQL using a MySQL driver such as
mysql-connector-python. - The connector is imported using
import mysql.connector. mysql.connector.connect()establishes the MySQL connection.- The
databaseparameter can select the Database when creating the connection. con.cursor()creates a Cursor object.cursor.execute()executes an SQL statement.CREATE TABLE IF NOT EXISTSavoids an error when the named table already exists.%splaceholders are used for parameter values with MySQL Connector/Python.- Values should be supplied separately instead of concatenating user input directly into SQL strings.
execute()can be used to insert a single parameter set.executemany()is useful for inserting multiple parameter sets using the same SQL statement.commit()commits transaction changes.rollback()can cancel applicable uncommitted changes.SELECTretrieves records.fetchall()retrieves all remaining rows from the result set.- Each fetched employee record is normally represented as a tuple.
- Tuple indexes such as
row[0]androw[1]can access individual columns. cursor.rowcountprovides information about affected rows.- Running the same INSERT program repeatedly can create duplicate records unless the schema or application prevents them.
- A primary key can be used to enforce uniqueness for employee numbers.
- MySQL Connector errors can be handled using
mysql.connector.Error. - The Cursor and Connection should be closed after Database operations are complete.
Summary
| Topic | Description |
|---|---|
| Database | MySQL |
| Python Module | mysql.connector |
| Database Used | employee_db |
| Table | employees |
| Connection | mysql.connector.connect() |
| Cursor | con.cursor() |
| Create Table | CREATE TABLE |
| Single Execution | execute() |
| Multiple Parameter Sets | executemany() |
| Insert | INSERT INTO |
| Save Changes | commit() |
| Cancel Uncommitted Changes | rollback() |
| Retrieve | SELECT |
| Fetch Records | fetchall() |
| Error Class | mysql.connector.Error |
| Cleanup | cursor.close() and con.close() |
Quick Revision
import mysql.connector
│
▼
mysql.connector.connect()
│
▼
employee_db
│
▼
con.cursor()
│
▼
CREATE TABLE employees
│
▼
Prepare INSERT Query
│
▼
Prepare Employee Records
│
▼
cursor.executemany()
│
▼
con.commit()
│
▼
SELECT * FROM employees
│
▼
cursor.fetchall()
│
▼
for row in data
│
▼
print(row)
│
▼
Close Cursor
│
▼
Close Connection
Part 17 - Final Concept
Python Application
│
▼
mysql.connector
│
▼
mysql.connector.connect()
│
▼
MySQL Server
│
▼
employee_db
│
▼
Cursor
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
CREATE INSERT SELECT
│ │ │
▼ ▼ ▼
employees executemany() fetchall()
│ │
▼ ▼
commit() Employee Data
│
▼
Display
│
▼
Close DB Resources
Part 17 Completed
In this part, we learned how to connect Python with MySQL, create the employees table, insert single and multiple employee records, commit changes, retrieve records using SELECT and fetchall(), and display employee information.
We also covered dynamic keyboard input, parameterized queries, execute(), executemany(), commit(), rollback(), error handling, duplicate records and primary keys.
Introduction
In this application, we will copy employee records from a MySQL Database into an Oracle Database.
The employee records are already available in the employees table of the MySQL Database.
Our Python program performs two main operations:
- Read all employee records from the MySQL Database.
- Insert those employee records into the Oracle Database.
MySQL Database
│
▼
employees Table
│
▼
SELECT Records
│
▼
fetchall()
│
▼
Python List
│
▼
Oracle Database
│
▼
employees Table
Therefore, Python acts as a bridge between the two databases.
Objective of the Program
The objective of this application is:
Copy Employee Records FROM MySQL employees Table TO Oracle employees Table
The complete data-transfer process is:
Source Database
│
▼
MySQL
│
▼
Read Records
│
▼
Python List
│
▼
Insert Records
│
▼
Oracle
│
▼
Destination Database
Two Stages of the Program
The complete application is divided into two stages.
Stage 1 — Read Data from MySQL
MySQL │ ▼ SELECT * FROM employees │ ▼ fetchall() │ ▼ Python List
Stage 2 — Write Data into Oracle
Python List
│
▼
executemany()
│
▼
Oracle employees Table
│
▼
commit()
Complete Program
main.py
No output captured.
Program Overview
The program contains two separate Database operations.
Python Program
│
┌────────────┴────────────┐
│ │
▼ ▼
MySQL Operation Oracle Operation
│ │
▼ ▼
Connect to MySQL Connect to Oracle
│ │
▼ ▼
SELECT Records INSERT Records
│ ▲
▼ │
fetchall() │
│ │
▼ │
Python List ──────────────────┘
MySQL is the source Database, while Oracle is the destination Database.
Part 1 — Reading Data from MySQL Database
The first section of the program retrieves all employee records from MySQL.
The steps are:
Import Modules
│
▼
Connect MySQL
│
▼
Create Cursor
│
▼
SELECT employees
│
▼
fetchall()
│
▼
Create List
│
▼
Store Employee Tuples
Step 1 — Import Required Modules
The program starts by importing two Database modules:
import mysql.connector import cx_Oracle
The modules have different purposes.
| Module | Database | Purpose |
|---|---|---|
mysql.connector |
MySQL | Communicates with the MySQL Database |
cx_Oracle |
Oracle | Communicates with the Oracle Database |
Python │ ├──── mysql.connector ────► MySQL │ └──── cx_Oracle ──────────► Oracle
Step 2 — Connect to MySQL Database
The program establishes a connection with MySQL using:
con = mysql.connector.connect(
host='localhost',
database='durgadb',
user='root',
password='root'
)
The connection information used in the program is:
| Parameter | Value |
|---|---|
| Host | localhost |
| Database | durgadb |
| User | root |
| Password | root |
The returned Connection object is stored in:
con
MySQL Connection Flow
Python Program
│
▼
mysql.connector
│
▼
connect()
│
▼
MySQL Server
│
▼
durgadb
Step 3 — Create MySQL Cursor
After establishing the connection, the program creates a Cursor object.
cursor = con.cursor()
The Cursor object is required for executing SQL statements.
Connection
│
▼
cursor()
│
▼
Cursor Object
│
▼
Execute SQL Queries
Step 4 — Execute SELECT Query
The program retrieves all employee records using:
cursor.execute("select * from employees")
The SQL statement is:
SELECT * FROM employees;
Here:
| Part | Meaning |
|---|---|
SELECT |
Retrieve data |
* |
All columns |
FROM employees |
Retrieve data from the employees table |
Step 5 — Fetch All Employee Records
After executing the SELECT query, the program retrieves all rows using:
data = cursor.fetchall()
fetchall() retrieves all employee records returned by the SELECT query.
The records are stored in:
data
Conceptually, the result can look like:
[
(100, 'Sachin', 1000.0, 'Mumbai'),
(200, 'Dhoni', 2000.0, 'Ranchi'),
(300, 'Kohli', 3000.0, 'Delhi')
]
SELECT Query
│
▼
fetchall()
│
▼
All Employee Rows
│
▼
data
Step 6 — Create an Empty List
An empty list is created:
list = []
This list is used as temporary storage for employee records.
MySQL │ ▼ Employee Records │ ▼ Python List │ ▼ Oracle
Initially:
list = []
After processing the employee records, it will contain employee tuples.
Step 7 — Process Every Employee Record
The program processes the rows returned by fetchall() using a for loop:
for row in data:
During each iteration, row contains one employee record.
For example:
row = (100, 'Sachin', 1000.0, 'Mumbai')
The column values can be accessed using indexes:
| Index | Employee Information |
|---|---|
row[0] |
Employee Number |
row[1] |
Employee Name |
row[2] |
Employee Salary |
row[3] |
Employee Address |
Step 8 — Convert Each Row into a Tuple
Each employee row is explicitly converted into a tuple:
t = (row[0], row[1], row[2], row[3])
For example:
row │ ▼ (100, 'Sachin', 1000.0, 'Mumbai') │ ▼ t │ ▼ (100, 'Sachin', 1000.0, 'Mumbai')
The tuple contains all four employee values.
Step 9 — Append Tuple to the List
The employee tuple is added to the list using:
list.append(t)
The loop performs this operation for every employee.
Initial:
list = []
After Employee 1:
list = [
(100, 'Sachin', 1000.0, 'Mumbai')
]
After Employee 2:
list = [
(100, 'Sachin', 1000.0, 'Mumbai'),
(200, 'Dhoni', 2000.0, 'Ranchi')
]
After Employee 3:
list = [
(100, 'Sachin', 1000.0, 'Mumbai'),
(200, 'Dhoni', 2000.0, 'Ranchi'),
(300, 'Kohli', 3000.0, 'Delhi')
]
This list will later be passed to Oracle.
How MySQL Data is Converted
MySQL employees Table
│
▼
SELECT *
│
▼
fetchall()
│
▼
data
│
▼
for row in data
│
▼
(row[0], row[1], row[2], row[3])
│
▼
t
│
▼
list.append(t)
│
▼
Python List
MySQL Exception Handling
MySQL Database errors are handled using:
except mysql.connector.DatabaseError as e:
If a Database error occurs, the exception object is stored in:
e
The error information is displayed using:
print("There is a problem with MySql :", e)
MySQL rollback()
If a MySQL Database error occurs, the program checks the Connection object:
if con:
con.rollback()
rollback() cancels applicable temporary or uncommitted transaction changes.
Database Error
│
▼
con exists?
│
▼
con.rollback()
│
▼
Cancel Uncommitted Changes
Close MySQL Resources
The MySQL Cursor and Connection are closed inside the finally block.
finally:
if cursor:
cursor.close()
if con:
con.close()
The resources are closed in this order:
Cursor │ ▼ cursor.close() │ ▼ Connection │ ▼ con.close()
At this point, reading from the MySQL Database is complete.
Part 2 — Writing Data into Oracle Database
After retrieving the employee records from MySQL, the second part of the program inserts them into Oracle.
Python List
│
▼
Connect Oracle
│
▼
Create Cursor
│
▼
Prepare INSERT Query
│
▼
executemany()
│
▼
Oracle employees Table
│
▼
commit()
Step 10 — Connect to Oracle Database
The program establishes an Oracle Database connection using:
con = cx_Oracle.connect('scott/tiger@localhost')
The connection details are:
| Information | Value |
|---|---|
| Username | scott |
| Password | tiger |
| Database | localhost |
Python │ ▼ cx_Oracle │ ▼ connect() │ ▼ Oracle Database
Step 11 — Create Oracle Cursor
A new Cursor object is created for the Oracle connection:
cursor = con.cursor()
This Cursor will execute the Oracle INSERT statement.
Oracle Connection
│
▼
con.cursor()
│
▼
Oracle Cursor
│
▼
Execute INSERT
Step 12 — Prepare Oracle INSERT Query
The program creates a parameterized INSERT query:
sql = "insert into employees values(:eno,:ename,:esal,:eaddr)"
The placeholders are:
| Placeholder | Value |
|---|---|
:eno |
Employee Number |
:ename |
Employee Name |
:esal |
Employee Salary |
:eaddr |
Employee Address |
The query inserts one employee structure into the Oracle employees table.
Understanding the Parameterized Query
insert into employees
values(:eno, :ename, :esal, :eaddr)
│ │ │ │
▼ ▼ ▼ ▼
eno ename esal eaddr
The employee values come from the tuples stored in the Python list.
For example:
(100, 'Sachin', 1000.0, 'Mumbai') │ │ │ │ ▼ ▼ ▼ ▼ :eno :ename :esal :eaddr
Step 13 — Insert All Records using executemany()
All employee records are inserted using:
cursor.executemany(sql, list)
executemany() executes the same parameterized INSERT statement for all tuples available in the list.
Python List
│
├── Employee 1
├── Employee 2
└── Employee 3
│
▼
executemany()
│
▼
Oracle employees Table
Therefore, we do not need to call execute() separately for every employee record.
How executemany() Works in This Program
sql
│
│ "insert into employees
│ values(:eno,:ename,:esal,:eaddr)"
│
├────────────────────────────┐
│ │
▼ ▼
Parameterized Query Python List
│
├── Tuple 1
├── Tuple 2
└── Tuple 3
│
▼
executemany()
│
▼
Insert All Employees
│
▼
Oracle Database
Step 14 — Commit the Oracle Transaction
After inserting all records, the program executes:
con.commit()
commit() permanently saves the copied employee records in the Oracle Database.
executemany()
│
▼
Records Inserted
│
▼
Uncommitted Changes
│
▼
con.commit()
│
▼
Records Permanently Saved
Step 15 — Display Success Message
After the records are committed successfully, the program displays:
Records Copied from MySQL Database to Oracle Database Successfully
The statement responsible for this output is:
print("Records Copied from MySQL Database to Oracle Database Successfully")
Expected Output
If all operations complete successfully, the program displays:
Records Copied from MySQL Database to Oracle Database Successfully
The employee records that existed in the MySQL employees table are now inserted into the Oracle employees table.
Oracle Exception Handling
Oracle Database errors are handled using:
except cx_Oracle.DatabaseError as e:
If an error occurs, it is stored in:
e
The program displays the error using:
print("There is a problem with sql", e)
Oracle rollback()
If an error occurs while inserting the employee records, the program executes:
if con:
con.rollback()
This rolls back applicable uncommitted Oracle transaction changes.
INSERT Records
│
▼
Database Error
│
▼
con.rollback()
│
▼
Cancel Uncommitted Changes
Close Oracle Resources
Finally, the Oracle Cursor and Connection are closed:
finally:
if cursor:
cursor.close()
if con:
con.close()
The cleanup flow is:
Oracle Cursor
│
▼
cursor.close()
│
▼
Oracle Connection
│
▼
con.close()
Complete Data Transfer Flow
START
│
▼
Import mysql.connector
Import cx_Oracle
│
▼
Connect to MySQL
│
▼
Create Cursor
│
▼
SELECT * FROM employees
│
▼
fetchall()
│
▼
Employee Rows
│
▼
Create List
│
▼
for row in data
│
▼
Convert Row to Tuple
│
▼
list.append()
│
▼
More MySQL Records?
/ \
Yes No
│ │
└── Repeat ▼
Close MySQL
Resources
│
▼
Connect to Oracle
│
▼
Create Cursor
│
▼
Prepare INSERT SQL
│
▼
cursor.executemany()
│
▼
Insert Employee Records
│
▼
con.commit()
│
▼
Display Success
│
▼
Close Oracle Resources
│
▼
END
Source to Destination Flow
SOURCE
MySQL Database
│
▼
durgadb
│
▼
employees
│
▼
SELECT *
│
▼
fetchall()
│
▼
data
│
▼
Python List
│
▼
executemany()
│
▼
employees
│
▼
Oracle Database
DESTINATION
Role of the Python List
The Python list works as temporary storage between the two databases.
MySQL │ ▼ fetchall() │ ▼ Python List │ ▼ executemany() │ ▼ Oracle
For example:
list = [
(100, 'Sachin', 1000.0, 'Mumbai'),
(200, 'Dhoni', 2000.0, 'Ranchi'),
(300, 'Kohli', 3000.0, 'Delhi')
]
These tuples can then be passed directly to:
cursor.executemany(sql, list)
MySQL and Oracle Responsibilities
| Operation | MySQL | Oracle |
|---|---|---|
| Role | Source | Destination |
| Python Module | mysql.connector |
cx_Oracle |
| Main SQL | SELECT |
INSERT |
| Fetch | fetchall() |
Not required |
| Insert | Not required in transfer stage | executemany() |
| Commit | Not required for SELECT | commit() |
Methods Used
| Method | Purpose |
|---|---|
mysql.connector.connect() |
Connects Python to the MySQL Database |
cx_Oracle.connect() |
Connects Python to the Oracle Database |
cursor() |
Creates a Cursor object |
execute() |
Executes the MySQL SELECT query |
fetchall() |
Retrieves all employee records from MySQL |
append() |
Adds each employee tuple to the Python list |
executemany() |
Inserts multiple employee records into Oracle |
commit() |
Permanently saves copied records |
rollback() |
Rolls back applicable uncommitted changes when an error occurs |
close() |
Closes Cursor and Connection resources |
Difference Between execute(), fetchall() and executemany()
| Method | Purpose in This Program |
|---|---|
execute() |
Executes the SELECT query against MySQL |
fetchall() |
Retrieves all rows returned by MySQL |
executemany() |
Executes the Oracle INSERT operation for multiple employee tuples |
execute() │ ▼ Run SELECT │ ▼ fetchall() │ ▼ Get Records │ ▼ executemany() │ ▼ Insert Records
Program Explanation — Complete Sequence
The complete program executes in the following sequence:
1. Import mysql.connector. 2. Import cx_Oracle. 3. Connect to the MySQL durgadb Database. 4. Create the MySQL Cursor. 5. Execute SELECT * FROM employees. 6. Retrieve all employee records using fetchall(). 7. Create an empty Python list. 8. Process every employee record. 9. Convert every row into a tuple. 10. Append every tuple to the list. 11. Handle possible MySQL Database errors. 12. Close the MySQL Cursor. 13. Close the MySQL Connection. 14. Connect to the Oracle Database. 15. Create the Oracle Cursor. 16. Prepare the parameterized INSERT query. 17. Pass the SQL query and employee list to executemany(). 18. Insert all employee records into Oracle. 19. Execute commit(). 20. Display the success message. 21. Handle possible Oracle Database errors. 22. Close the Oracle Cursor. 23. Close the Oracle Connection.
Important Points
- The program works with two different Database systems.
- MySQL is used as the source Database.
- Oracle is used as the destination Database.
mysql.connectoris used to communicate with MySQL.cx_Oracleis used to communicate with Oracle.- The MySQL Database used in the program is
durgadb. - The program retrieves employee records using
SELECT * FROM employees. fetchall()retrieves all employee records from MySQL.- A Python list is used as temporary storage for the records.
- Each employee record is stored as a tuple.
list.append(t)adds each employee tuple to the list.- The Oracle INSERT statement uses placeholders such as
:eno,:ename,:esaland:eaddr. executemany()inserts all employee tuples into Oracle.commit()permanently saves the inserted Oracle records.rollback()is used when a Database error occurs.- MySQL and Oracle errors are handled separately.
- The program has separate
try-except-finallyblocks for the two Database operations. - The MySQL Cursor and Connection are closed after reading the data.
- The Oracle Cursor and Connection are closed after inserting the data.
- The Oracle
employeestable should already exist with a compatible structure before the records are inserted.
Summary
| Topic | Description |
|---|---|
| Source Database | MySQL |
| Source Database Name | durgadb |
| Destination Database | Oracle |
| Table | employees |
| MySQL Module | mysql.connector |
| Oracle Module | cx_Oracle |
| Read SQL | SELECT * FROM employees |
| Read Method | fetchall() |
| Temporary Storage | Python List |
| Record Format | Tuple |
| List Method | append() |
| Oracle Insert Method | executemany() |
| Save Changes | commit() |
| Error Handling | rollback() |
| Resource Cleanup | cursor.close() and con.close() |
Quick Revision
import mysql.connector
import cx_Oracle
│
▼
Connect MySQL
│
▼
SELECT employees
│
▼
fetchall()
│
▼
Employee Records
│
▼
Create Python List
│
▼
Convert Rows to Tuples
│
▼
append()
│
▼
Close MySQL
│
▼
Connect Oracle
│
▼
Prepare INSERT Query
│
▼
executemany()
│
▼
commit()
│
▼
Records Copied
│
▼
Close Oracle
Part 18 — Final Concept
DATABASE-TO-DATABASE COPY
Python Program
│
┌─────────────┴─────────────┐
│ │
▼ ▼
mysql.connector cx_Oracle
│ │
▼ ▼
MySQL Oracle
│ ▲
▼ │
employees Table │
│ │
▼ │
SELECT * │
│ │
▼ │
fetchall() │
│ │
▼ │
Python List │
│ │
└──────► executemany() ─────┘
│
▼
commit()
│
▼
Copy Completed
Part 18 Completed
In this application, we learned how to transfer employee records from a MySQL Database to an Oracle Database using Python.
The records are retrieved from MySQL using fetchall(), temporarily stored as tuples inside a Python list, and inserted into Oracle using executemany().
Finally, commit() permanently saves the copied records in Oracle, while rollback() provides transaction handling when a Database error occurs.