Below you can see the tables in my sqlite3 database:
songs
files
tags
playlists
These are the relationships between the tables:
One To One: Songs and files
Many To Many: Songs and tags, Songs and playlists
Below you can see the table queries I am using:
create_songs_table_query = """ CREATE TABLE IF NOT EXISTS songs (
song_id integer PRIMARY KEY AUTOINCREMENT,
title text NOT NULL,
artist text NOT NULL,
added_timestamp integer NOT NULL,
file_id INTEGER NULL,
FOREIGN KEY (file_id)
REFERENCES files (file_id)
ON DELETE CASCADE
); """
create_files_table_query = """ CREATE TABLE IF NOT EXISTS files (
file_id integer PRIMARY KEY AUTOINCREMENT,
filename text NULL,
size integer NULL,
song_id INTEGER NOT NULL,
FOREIGN KEY (song_id)
REFERENCES songs (song_id)
ON DELETE CASCADE
); """
create_tags_table_query = """CREATE TABLE IF NOT EXISTS tags (
tag_id integer PRIMARY KEY AUTOINCREMENT,
tag_text text NOT NULL,
tag_timestamp integer NULL,
); """
create_songs_tags_table_query = """CREATE TABLE IF NOT EXISTS songs_tags (
song_tag_id integer PRIMARY KEY AUTOINCREMENT,
song_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
FOREIGN KEY (song_id)
REFERENCES songs (song_id)
ON DELETE CASCADE,
FOREIGN KEY (tag_id)
REFERENCES tags (tag_id)
ON DELETE CASCADE
); """
create_playlists_table_query = """CREATE TABLE IF NOT EXISTS playlists (
playlist_id integer PRIMARY KEY AUTOINCREMENT,
playlist_title text NOT NULL,
created_timestamp INTEGER NOT NULL,
updated_timestamp INTEGER NULL,
); """
create_songs_playlists__table_query = """CREATE TABLE IF NOT EXISTS songs_playlists (
song_playlist_id integer PRIMARY KEY AUTOINCREMENT,
song_id INTEGER NOT NULL,
playlist_id INTEGER NOT NULL,
FOREIGN KEY (song_id)
REFERENCES songs (song_id)
ON DELETE CASCADE,
FOREIGN KEY (playlist_id)
REFERENCES playlists (playlist_id)
ON DELETE CASCADE
); """
I am trying sucessfully to get the total songs each tag has and order by it:
SELECT tags.tag_id, tags.tag_text, COUNT(tags.tag_id) AS total, tags.included, tags.tag_timestamp
FROM tags
JOIN songs_tags ON tags.tag_id = songs_tags.tag_id
GROUP BY songs_tags.tag_id
ORDER BY total DESC
This is the query to order by tags.tag_text:
SELECT tags.tag_id, tags.tag_text, COUNT(tags.tag_id) AS total, tags.included, tags.tag_timestamp
FROM tags
JOIN songs_tags ON tags.tag_id = songs_tags.tag_id
WHERE tags.included = 1
GROUP BY songs_tags.tag_id
ORDER BY tags.tag_text
I am using Python and Pycharm. Python doesn't return any records and Pycharm shows me the following pop up in the editor window:
Nondeterministic value: column tag_text is neither aggregated, nor mentioned in GROUP BY clause
Although, if I run the query from PyCharm's database console I get the desired results.
It's a bit tricky, any ideas ?
Writer the query correctly, so the SELECT and GROUP BY columns are consistent:
SELECT t.tag_id, t.tag_text, COUNT(*) AS total, t.included, t.tag_timestamp
FROM tags t JOIN
songs_tags st
ON t.tag_id = st.tag_id
WHERE t.included = 1
GROUP BY t.tag_id, t.tag_text, t.included, t.tag_timestamp
ORDER BY t.tag_text;
This also introduced table alias so the query is easier to write and to read.
Related
tblcustomer = """ CREATE TABLE IF NOT EXISTS Customer
(
CustomerID INT,
CustomerName TEXT,
Address TEXT,
Postcode TEXT,
EmailAddress TEXT,
primary key(CustomerID AUTOINCREMENT)
)"""
cursor.execute(tblcustomer)
connection.commit()
This is my table (I'm using sqlite3), but it returns 'null' to the table values. For my user inputs I just asked for the other 4 values and inserted them into the table, omitting 'CustomerID'. How do I fix it so it actually autoincrements?
Here's how you can modify your table to include an AUTOINCREMENT column for the CustomerID field:
CREATE TABLE IF NOT EXISTS Customer(
CustomerID INTEGER PRIMARY KEY AUTOINCREMENT,
CustomerName TEXT,
Address TEXT,
Postcode TEXT,
EmailAddress TEXT)
I am trying to get my head around the 'On Duplicate Key' mysql statement. I have the following table:
id (primary key autoincr) / server id (INT) / member id (INT UNIQUE KEY) / basket (VARCHAR) / shop (VARCHAR UNIQUE KEY)
In this table each member can have two rows, one for each of the shops (shopA and shopB). I want to INSERT if there is no match for both the member id and shop. If there is a match I want it to update the basket to concat the current basket with additional information.
I am trying to use:
"INSERT INTO table_name (server_id, member_id, basket, shop) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE basket = CONCAT (basket,%s)"
Currently if there is an entry for the member for shopA when this runs with basket for shopB it adds the basket info to the shopA row instead of creating a new one.
Hope all this makes sense! Thanks in advance!
UPDATE: As requested here is the create table sql statement:
CREATE TABLE table_name ( member_id bigint(20) NOT NULL, server_id bigint(11) NOT NULL, basket varchar(10000) NOT NULL, shop varchar(30) NOT NULL, notes varchar(1000) DEFAULT NULL, PRIMARY KEY (member_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
In this table each member can have two rows, one for each of the shops
(shopA and shopB)
This means that member_id should not be the primary key of the table because it is not unique.
You need a composite primary key for the columns member_id and shop:
CREATE TABLE table_name (
member_id bigint(20) NOT NULL,
server_id bigint(11) NOT NULL,
basket varchar(10000) NOT NULL,
shop varchar(30) NOT NULL,
notes varchar(1000) DEFAULT NULL,
PRIMARY KEY (member_id, shop)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
See a simplified demo.
In the SQLite command line, the command .schema can be used to export a database schema in SQL syntax, and that export can be used to rebuild a database of the same structure:
.output folderpath/schema.sql
.schema
Saves the following to a file named "schema.sql":
CREATE TABLE mytable (id INTEGER NOT NULL, name TEXT NOT NULL, date DATETIME, PRIMARY KEY (id), FOREIGN KEY (name) REFERENCES mytable2 (na ...
Can the same output .sql file be achieved using Python's sqlite3 library without a custom function?
There are several questions on Stack Overflow with similar titles, but I didn't find any that are actually trying to get the full schema (they are actually looking for PRAGMA table_info which does not have the CREATE TABLE, etc. statements in the output).
Well. Rewritten the answer above. It that exactly what you need?
import sqlite3
dbname = 'chinook.db'
with sqlite3.connect(dbname) as con:
cursor = con.cursor()
cursor.execute('select sql from sqlite_master')
for r in cursor.fetchall():
print(r[0])
cursor.close()
With the test sqlite3 database I received the following:
CREATE TABLE "albums"
(
[AlbumId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Title] NVARCHAR(160) NOT NULL,
[ArtistId] INTEGER NOT NULL,
FOREIGN KEY ([ArtistId]) REFERENCES "artists" ([ArtistId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE TABLE sqlite_sequence(name,seq)
CREATE TABLE "artists"
(
[ArtistId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(120)
)
CREATE TABLE "customers"
(
[CustomerId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[FirstName] NVARCHAR(40) NOT NULL,
[LastName] NVARCHAR(20) NOT NULL,
[Company] NVARCHAR(80),
[Address] NVARCHAR(70),
[City] NVARCHAR(40),
[State] NVARCHAR(40),
[Country] NVARCHAR(40),
[PostalCode] NVARCHAR(10),
[Phone] NVARCHAR(24),
[Fax] NVARCHAR(24),
[Email] NVARCHAR(60) NOT NULL,
[SupportRepId] INTEGER,
FOREIGN KEY ([SupportRepId]) REFERENCES "employees" ([EmployeeId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE TABLE "employees"
(
[EmployeeId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[LastName] NVARCHAR(20) NOT NULL,
[FirstName] NVARCHAR(20) NOT NULL,
[Title] NVARCHAR(30),
[ReportsTo] INTEGER,
[BirthDate] DATETIME,
[HireDate] DATETIME,
[Address] NVARCHAR(70),
[City] NVARCHAR(40),
[State] NVARCHAR(40),
[Country] NVARCHAR(40),
[PostalCode] NVARCHAR(10),
[Phone] NVARCHAR(24),
[Fax] NVARCHAR(24),
[Email] NVARCHAR(60),
FOREIGN KEY ([ReportsTo]) REFERENCES "employees" ([EmployeeId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE TABLE "genres"
(
[GenreId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(120)
)
CREATE TABLE "invoices"
(
[InvoiceId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[CustomerId] INTEGER NOT NULL,
[InvoiceDate] DATETIME NOT NULL,
[BillingAddress] NVARCHAR(70),
[BillingCity] NVARCHAR(40),
[BillingState] NVARCHAR(40),
[BillingCountry] NVARCHAR(40),
[BillingPostalCode] NVARCHAR(10),
[Total] NUMERIC(10,2) NOT NULL,
FOREIGN KEY ([CustomerId]) REFERENCES "customers" ([CustomerId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE TABLE "invoice_items"
(
[InvoiceLineId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[InvoiceId] INTEGER NOT NULL,
[TrackId] INTEGER NOT NULL,
[UnitPrice] NUMERIC(10,2) NOT NULL,
[Quantity] INTEGER NOT NULL,
FOREIGN KEY ([InvoiceId]) REFERENCES "invoices" ([InvoiceId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([TrackId]) REFERENCES "tracks" ([TrackId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE TABLE "media_types"
(
[MediaTypeId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(120)
)
CREATE TABLE "playlists"
(
[PlaylistId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(120)
)
CREATE TABLE "playlist_track"
(
[PlaylistId] INTEGER NOT NULL,
[TrackId] INTEGER NOT NULL,
CONSTRAINT [PK_PlaylistTrack] PRIMARY KEY ([PlaylistId], [TrackId]),
FOREIGN KEY ([PlaylistId]) REFERENCES "playlists" ([PlaylistId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([TrackId]) REFERENCES "tracks" ([TrackId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
None
CREATE TABLE "tracks"
(
[TrackId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(200) NOT NULL,
[AlbumId] INTEGER,
[MediaTypeId] INTEGER NOT NULL,
[GenreId] INTEGER,
[Composer] NVARCHAR(220),
[Milliseconds] INTEGER NOT NULL,
[Bytes] INTEGER,
[UnitPrice] NUMERIC(10,2) NOT NULL,
FOREIGN KEY ([AlbumId]) REFERENCES "albums" ([AlbumId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([GenreId]) REFERENCES "genres" ([GenreId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([MediaTypeId]) REFERENCES "media_types" ([MediaTypeId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE INDEX [IFK_AlbumArtistId] ON "albums" ([ArtistId])
CREATE INDEX [IFK_CustomerSupportRepId] ON "customers" ([SupportRepId])
CREATE INDEX [IFK_EmployeeReportsTo] ON "employees" ([ReportsTo])
CREATE INDEX [IFK_InvoiceCustomerId] ON "invoices" ([CustomerId])
CREATE INDEX [IFK_InvoiceLineInvoiceId] ON "invoice_items" ([InvoiceId])
CREATE INDEX [IFK_InvoiceLineTrackId] ON "invoice_items" ([TrackId])
CREATE INDEX [IFK_PlaylistTrackTrackId] ON "playlist_track" ([TrackId])
CREATE INDEX [IFK_TrackAlbumId] ON "tracks" ([AlbumId])
CREATE INDEX [IFK_TrackGenreId] ON "tracks" ([GenreId])
CREATE INDEX [IFK_TrackMediaTypeId] ON "tracks" ([MediaTypeId])
CREATE TABLE sqlite_stat1(tbl,idx,stat)
Here are my tables. I get 0 rows return.
CREATE TABLE Artist (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
name TEXT UNIQUE
);
CREATE TABLE Album (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
artist_id INTEGER,
title TEXT UNIQUE
);
CREATE TABLE Genre (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
name TEXT
);
CREATE TABLE Track (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
title TEXT UNIQUE,
album_id INTEGER,
genre_id INTEGER,
len INTEGER, rating INTEGER, count INTEGER
);
Here my SQL code:
SELECT Track.title, Artist.name, Album.title, Genre.name
FROM Track JOIN Genre JOIN Album JOIN Artist
ON Track.genre_id = Genre.id and Track.album_id = Album.id
WHERE Album.artist_id = Artist.id
ORDER BY Artist.name LIMIT 3
I appreciate your looking into this problem.
You code is correct sofar, but you need to fill the just created tables with records.
For example by running (untested):
INSERT INTO Artist (name) VALUES ('Artist 1'), ('Artist 2');
INSERT INTO Genre (name) VALUES ('Genre 1'), ('Genre 2');
INSERT INTO Album (title, artist_id) VALUES ('Title 1', 1);
INSERT INTO Track(title, album_id,
genre_id, len, rating, count)
VALUES ('Track 1', 1, 1, 0, 0, 0);
Also you should declare artist_id, album_id and genre_id columns as foreign keys.
I am trying to create a relational database in python with sqlite3. I am a little fussy on how to connect the tables in the database so that one entity connects to another via the second table. I want to be able to make a search on a persons name via a webpage and then find the parents related to that person. Im not sure if I need two tables or three.
This is how my code looks like right now:
class Database:
'''Initiates the database.'''
def __init__(self):
self.db = sqlite3.connect('family2.db')
def createTable(self):
r = self.db.execute('''
CREATE TABLE IF NOT EXISTS family2 (
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
fname TEXT,
sname TEXT,
birthdate TEXT,
deathdate TEXT,
mother TEXT,
father TEXT
)''')
self.db.commit()
g = self.db.execute('''CREATE TABLE IF NOT EXISTS parents(
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
mother TEXT,
father TEXT)''')
self.db.commit()
b = self.db.execute('''CREATE TABLE IF NOT EXISTS relations(
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
family2,
parents TEXT
)''')
self.db.commit()
Thanks in advance!
You don't need multiple tables; you can store the IDs of the parents in the table itself:
CREATE TABLE persons(
id INTEGER PRIMARY KEY,
name TEXT,
mother_id INT,
father_id INT
);
You can then find the mother of a person that is identified by its name with a query like this:
SELECT *
FROM persons
WHERE id = (SELECT mother_id
FROM persons
WHERE name = '...')