Story: Assume you work for the Finxter Academy. Your boss asks you to import an existing CSV file containing fictitious users to SQLite3
.
What is SQLite3
, you ask!
SQLite3
is an ANSI-C source-code file that offers a light-weight database
with the following qualities:
- Easy to compile and incorporate into projects.
- No external dependencies.
- Supports cross-platforms.
- Easy to port to other systems.
π‘ Note: To follow along, click here to download the Finxters CSV file. Then, move this file to the current working directory.
Related Article:
Preparation
- The Pandas library enables access to/from a CSV file.
To install this library, navigate to an IDE terminal. At the command prompt ($
), execute the code below. For the terminal used in this example, the command prompt is a dollar sign ($
). Your terminal prompt may be different.
π‘ Note: The
library is built-in to Python and does not require installation. This library contains methods to import and select data to/from the database.SQLite3
$ pip install pandas
Hit the <Enter>
key on the keyboard to start the installation process.
If the installation was successful, a message displays in the terminal indicating the same.
Feel free to view the PyCharm installation guide for the required library.
Add the following code to the top of each code snippet. This snippet will allow the code in this article to run error-free.
import pandas as pd import csv from csv import reader import sqlite3
Create SQLite3 Database
The first step is to write a function that creates a SQLite3
database
.
Navigate to an IDE and perform the following steps:
- Create a new Python file (example:
users.py
). - Paste the code below (remember to add the Required Starter Code).
- Save and run the file.
def connect_db(db_name): try: con = sqlite3.connect(db_name) except: con = None return con con = connect_db('users.db') try: cur = con.cursor() print(con) print(cur) except: print('An error occurred.') con.close()
- Line [1] defines the function
connect_db
with one (1) argument: adatabase
name.- Line [2] executes the
try
statement.- The code on Line [3] executes. If the connection is successful, a connection object saves to
con
.
- The code on Line [3] executes. If the connection is successful, a connection object saves to
- Line [4] executes if the connection fails.
- The code on Line [5] executes. The variable
con
contains None.
- The code on Line [5] executes. The variable
- Line [6] returns
con
from theconnect_db
function.
- Line [2] executes the
- Line [7] calls the
connect_db
function and saves the return value tocon
. - Line [8] executes the
try
statement.- Line [9] creates a cursor class (see below) and assigns this value to
cur
. - Lines [10-11] output the values of
con
andcur
to the terminal.
- Line [9] creates a cursor class (see below) and assigns this value to
- Lines [12-13] execute if the
try
statement fails. - Line [14] closes the open connection.
π‘ Note: conn.cursor()
allows Python to execute commands against the SQLite3
database
for the duration of the script (or until the connection is closed).
Output
<sqlite3.Connection object at 0x000001B731552040> |
π‘ Note: You may want to remove Lines [10-11] before continuing.
Create a Table
The next step is to write a function that creates a
table.SQLite3
The query
below contains five (5) fields. These match the number of columns inside the CSV file.
π‘ Note: We matched the table field names to the CSV column names. However, you can use your own table field names.
def connect_db(db_name): try: con = sqlite3.connect(db_name) except: con = None return con def create_table(table_name): query = f'''CREATE TABLE IF NOT EXISTS {table_name} (FID INTEGER, fname VARCHAR(50), lname VARCHAR(50), rank VARCHAR(20), solved INTEGER);''' cur.execute(query) con = connect_db('users.db') try: cur = con.cursor() create_table('finxters') except: print('An error occurred.') con.close()
- Line [1] defines a function
create_table
with one (1) argument: atable
.- Line [2] creates a multi-line
query
. - Line [3] executes the
query
.
- Line [2] creates a multi-line
- Line [4] calls the
connect_db
function and saves the return value tocon
. - Line [5] executes the try statement.
- Line [6] creates a cursor class (see above) and assigns this value to
cur
. - Line [7] creates the
finxters table
if it does not exist.
- Line [6] creates a cursor class (see above) and assigns this value to
- Lines [8-9] execute if the
try
statement fails. - Line [10] closes the open connection.
After running this code (barring any unforeseen errors), a SQLite3
database
containing one (1) table
should now reside in the current working directory.
Inserting Records
The Finxter CSV file contains 50 records (plus a header row). Let’s add these records to the finxters table
.
To ensure that these records insert only once, we need to write a function ok_to_insert
that checks if the table is empty.
Then another function insert_recs
is written to insert rows from the CSV file into the table.
Finally, let’s put it all together for a functioning Python script.
π‘ Note: Remember to add the Required Start Code at the top.
The lines in yellow will be addressed below.
def connect_db(db_name): try: con = sqlite3.connect(db_name) except: con = None return con def create_table(table_name): query = f'''CREATE TABLE IF NOT EXISTS {table_name} (FID INTEGER, first_name VARCHAR(50), last_name VARCHAR(50), rank VARCHAR(20), solved INTEGER);''' cur.execute(query) def ok_to_insert(table_name): cur.execute(f'SELECT COUNT(*) from {table_name}') rows = int(cur.fetchone()[0]) return True if rows==0 else False def insert_recs(csv_file, table_name): with open(csv_file) as f: reader = csv.reader(f) for field in reader: cur.execute(f'INSERT INTO {table_name} VALUES (?,?,?,?,?);', field) con = connect_db('users.db') try: cur = con.cursor() create_table('finxters') if ok_to_insert('finxters'): insert_recs('finxters-sample.csv', 'finxters') except: print('An error occurred.') con.close()
- Line [1] creates a function
ok_to_insert
with one (1) argument: atable
. - Line [5] creates a function
insert_recs
with two (2) arguments: file, table.- Lines [6-9] loop through the CSV file, adding each CSV row to the
database table
.
For each column (field) to insert, the code expects a ‘?'
character. This character lets
you know what to expect. Here we retrieve five (5) columns. Therefore we must have five (5)SQLite3
'?'
characters separated by commas (,
).
- Lines [6-9] loop through the CSV file, adding each CSV row to the
- Line [10] executes the
try
statement.- Line [11] creates a cursor class (see above) and assigns this value to
cur
.
- Line [12] creates the table if it does not exist.
- Line [13] returns either True/False from the
ok_to_insert
function.- Line [14] executes and inserts the records into the table.
- Line [11] creates a cursor class (see above) and assigns this value to
- Lines [15-16] execute if an error occurs.
- Line [17] closes the open connection.
Fetching Data
Now that the sqlite3 table
contains data let’s fetch some records!
results = 'SELECT * FROM finxters WHERE solved > 1500;' rows = cur.execute(results).fetchall() for r in rows: print(r) con.close()
- Line [1] creates a
to fetch all records that meet the stated criteria. This saves to thequery
results
variable. - Line [2] executes the
query
created on Line [1] and returns Tuples. - Lines [3-4] loop through and output the rows that match the criteria (1 record/line).
Output (snippet)
('FID', 'fname', 'lname', 'rank', 'solved') |
𧩠Challenge: The Finxter Challenge is to write additional code to format the output as a table.