6.4. SQL CREATE
Constraint
UNIQUE
Constraint
PRIMARY KEY
Constraint
DEFAULT
Constraint
NOT NULL
Auto-value
NULL
Auto-value
AUTOINCREMENT
Auto-value
CURRENT_TIME
Auto-value
CURRENT_DATE
Auto-value
CURRENT_TIMESTAMP
Function
STRFTIME()
,DATETIME()
6.4.1. Create Table
CREATE TABLE astronauts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mycolumn01 INTEGER,
mycolumn02 INTEGER UNIQUE,
mycolumn03 REAL,
mycolumn04 FLOAT,
mycolumn05 TEXT,
mycolumn06 CHAR(2),
mycolumn07 VARCHAR(255),
mycolumn08 DATE,
mycolumn09 DATE DEFAULT CURRENT_DATE,
mycolumn10 TIME,
mycolumn11 TIME DEFAULT CURRENT_TIME,
mycolumn12 DATETIME,
mycolumn13 DATETIME DEFAULT NULL,
mycolumn14 DATETIME DEFAULT (DATETIME('NOW', 'LOCALTIME')),
mycolumn15 DATETIME DEFAULT (DATETIME('NOW', 'UTC')),
mycolumn16 DATETIME DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),
mycolumn17 TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
6.4.2. Add Column
ALTER TABLE astronauts
ADD mission_name TEXT;
6.4.3. Drop Column
SQLite3 does not support dropping columns with
ALTER TABLE
We have to do a workaround instead
Create a new table with all the columns (and data) that we want to keep
Drop the old table
Rename the new table with the old name.
Make sure you also take care of the Indexes and Views (if you have any)
Perform a
.schema astronauts
BEFORE you drop the tableUse this info to re-create the Indexes and Views after renaming the table back to its original name
CREATE TABLE astronauts_temp AS (
SELECT id, firstname, lastname, agency
FROM astronauts);
DROP TABLE astronauts;
ALTER TABLE astronauts_temp RENAME TO astronauts;
6.4.4. Example
CREATE TABLE astronauts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
firstname TEXT,
lastname TEXT,
agency TEXT);
CREATE TABLE IF NOT EXISTS sensor_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
datetime DATETIME DEFAULT (DATETIME('NOW', 'UTC')),
device_id INTEGER,
parameter TEXT,
value REAL,
unit TEXT);
6.4.5. Assignments
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: Database Create Table
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% English
# 1. Write SQL query to create table:
# - table: `contacts`
# - column: `id`, integer, primary key, autoincrement
# - column: `firstname`, text
# - column: `lastname`, text
# - column: `birthdate`, date, default null
# - use: IF NOT EXISTS
# 2. Run doctests - all must succeed
# %% Polish
# 1. Napisz zapytanie SQL aby stworzyć tabelę:
# - tabela: `contacts`
# - kolumna: `id`, integer, primary key, autoincrement
# - kolumna: `firstname`, text
# - kolumna: `lastname`, text
# - kolumna: `birthdate`, date, default null
# - użyj: IF NOT EXISTS
# 2. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> from pathlib import Path
>>> import sqlite3
>>> database = Path(__file__).parent.parent / 'shop.db'
>>> db = sqlite3.connect(database)
>>> try:
... _ = db.execute(result)
... db.commit()
... except sqlite3.OperationalError as e:
... assert 'table contacts already exists' in str(e)
>>> TABLES = 'SELECT `name` FROM `sqlite_master` WHERE `type`="table"'
>>> tables = {row[0] for row in db.execute(TABLES)}
>>> assert 'contacts' in tables, \
'You need to create table named `contacts`'
>>> PRAGMA = '''
... SELECT
... `m`.`name` AS `table_name`,
... `p`.`name` AS `col_name`,
... `p`.`type` AS `col_type`,
... `p`.`pk` AS `col_is_pk`,
... `p`.`dflt_value` AS `col_default_val`,
... `p`.[notnull] AS `col_is_not_null`
... FROM `sqlite_master` AS `m`
... LEFT OUTER JOIN `pragma_table_info`((`m`.`name`)) AS `p`
... ON `m`.`name` != `p`.`name`
... WHERE `m`.`type` = 'table'
... ORDER BY `table_name`
... '''
>>> pragma = db.execute(PRAGMA).fetchall()
>>> assert ('contacts', 'id', 'INTEGER', 1, None, 0) in pragma
>>> assert ('contacts', 'firstname', 'TEXT', 0, None, 0) in pragma
>>> assert ('contacts', 'lastname', 'TEXT', 0, None, 0) in pragma
>>> assert ('contacts', 'birthdate', 'DATE', 0, 'NULL', 0) in pragma
>>> db.close()
"""
# SQL query to create table:
# - table: `contacts`
# - column: `id`, integer, primary key, autoincrement
# - column: `firstname`, text
# - column: `lastname`, text
# - column: `birthdate`, date, default null
# - use: IF NOT EXISTS
# type: str
result = """
-- replace this comment
-- with your sql query
"""
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: Database Create Index
# - Difficulty: easy
# - Lines: 2
# - Minutes: 3
# %% English
# 1. Write SQL query to create index:
# - name: `contacts_lastname`
# - table: `contacts`
# - column: `lastname`
# - use: IF NOT EXISTS
# 2. Run doctests - all must succeed
# %% Polish
# 1. Napisz zapytanie SQL aby stworzyć indeks:
# - nazwa: `contacts_lastname`
# - tabela: `contacts`
# - kolumna: `lastname`
# - użyj: IF NOT EXISTS
# 2. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> from pathlib import Path
>>> import sqlite3
>>> database = Path(__file__).parent.parent / 'shop.db'
>>> db = sqlite3.connect(database)
>>> try:
... _ = db.execute(result)
... db.commit()
... except sqlite3.OperationalError as e:
... assert 'index contacts_lastname already exists' in str(e)
>>> INDEXES = 'SELECT `name` FROM `sqlite_master` WHERE `type`="index"'
>>> indexes = {row[0] for row in db.execute(INDEXES)}
>>> assert 'contacts_lastname' in indexes
>>> PRAGMA = '''
... SELECT
... `m`.`tbl_name` AS `table_name`,
... `il`.`name` AS `index_name`,
... `ii`.`name` AS `column_name`,
... CASE `il`.`origin` WHEN 'pk' THEN 1 ELSE 0 END AS `is_primary_key`,
... CASE `il`.[unique] WHEN 1 THEN 0 ELSE 1 END AS `non_unique`,
... `il`.[unique] AS `is_unique`,
... `il`.`partial`,
... `il`.`seq` AS `sequence_in_index`
... FROM `sqlite_master` AS `m`,
... `pragma_index_list`(`m`.`name`) AS `il`,
... `pragma_index_info`(`il`.`name`) AS `ii`
... WHERE `m`.`type` = 'table'
... AND `m`.`tbl_name` = 'contacts'
... GROUP BY
... `m`.`tbl_name`,
... `il`.`name`,
... `ii`.`name`,
... `il`.`origin`,
... `il`.`partial`,
... `il`.`seq`
... ORDER BY 1, 6
... '''
>>> pragma = db.execute(PRAGMA).fetchall()
>>> assert ('contacts', 'contacts_lastname', 'lastname', 0, 1, 0, 0, 0) in pragma
>>> db.close()
"""
# Write SQL query to create index:
# - name: `contacts_lastname`
# - table: `contacts`
# - column: `lastname`
# - use: IF NOT EXISTS
# type: str
result = """
-- replace this comment
-- with your sql query
"""