i want to create a table in sqlite3 with python put when i change number1 the name of table to the name of variable make the name of variable the name of table not the value in variable
db.execute("create table if not exists number1 (ID integer primary key autoincrement, item text, quantity integer,price_per_once integer, total integer)")
Thanks in advance
Concatenate a variable:
db.execute("create table if not exists " + table_name + " (ID integer primary key autoincrement, item text, quantity integer,price_per_once integer, total integer)")
Although if you're creating lots of tables with the same stucture, there's probably a better way to design your schema. Whatever the difference is between all these tables, it should probably just be a column in the table.
Have you tried something like this:
db.execute("create table " + tableNameVariable + " (...)")
Related
I am creating a program to practice MySQL where there is a table called inventory and the user adds to the table
item_code item_name price quantity
a000 a 100 100
I want to make it so that if the user inputs a000 then he gets a message of the item_code already being in the table
is there any way to do this
You can specify a UNIQUE index on the item_code field.
CREATE UNIQUE INDEX item_code_unique
ON inventory(item_code);
You can then use a try-catch block to catch any error from inserting duplicates.
try:
cursor.execute("INSERT INTO ....")
except MySQLdb.IntegrityError:
print("Duplicate entry")
See also: How to avoid duplicate entries in a MySQL database without throwing an error
Using MySQL UNIQUE Index To Prevent Duplicates
Try this:
import sqlite3
conn = sqlite3.connect("NameOfYourDatabase.db")
cur = conn.cursor()
cur.execute("""CREATE TABLE IF NOT EXISTS inventory (
item_code text UNIQUE,
item_name text,
price INT,
quantity INT
)"""
try:
#INSERT whatever you want into the db here
except sqlite3.IntegrityError:
print("Item code already exists")
You can also make your item_code a PRIMARY KEY as a PRIMARY KEY is automatically set as UNIQUE
REMEMBER: You can have only one PRIMARY KEY per table.
If your table is already created:
ALTER TABLE inventory
MODIFY item_code text NOT NULL UNIQUE;
With PRIMARY KEY:
ALTER TABLE inventory
ADD PRIMARY KEY (item_code);
Learn more in this website:
https://www.w3schools.com/sql/sql_unique.asp
I need to prompt a user to create a student table, check if a table with such a name exists in the database, and if not create it.
import sqlite3
conn = sqlite3.connect('School')
print ("Database has been created")
def create_table():
TableName = input("Enter table name: ")
tb_create ="""CREATE TABLE , (TableName,) (ID INT PRIMARY KEY,title VARCHAR(10), forename VARCHAR(20),
surname VARCHAR(20))"""
tb_exists ="SELECT name FROM sqlite_master WHERE type='table' AND name= ?", (TableName,)
if not conn.execute(tb_exists).fetchone():
conn.execute(tb_create)
print ("Table created successfully")
else:
print ("Table Exists!")
I know its possible to inser user inputed value into a table, but how do I create a table with inputed name? What should go after CREATE TABLE? If I use , (TableName,) the code wont compile.
Also, once the new table has been added to database, how do I indicate its name in INSER INTO query?
def insert_data():
conn.execute("INSERT INTO TableName (ID,title,forename,surname)VALUES \
(234,'Mr','XXX','XXX'")
conn.commit()
The correct syntax for a CREATE TABLE statement is:
CREATE TABLE tablename(column1 datatype1, column2 datatype2, ....)
Since you want the user to provide the name of the table, you can do it with string interpolation, because you can't pass it with a ? placeholder in the sql query as aparameter:
tb_create = f"CREATE TABLE [{TableName}](ID INTEGER PRIMARY KEY, title TEXT, forename TEXT, surname TEXT)"
The table's name must be enclosed inside square brackets, just in case the user provided a name that is not valid (for example it starts with digit or contains spaces).
Also, if you want the column ID to be autoincrement, you must use INTEGER instead of INT for its data type.
Also, there is no VARCHAR data type in SQLite. Use TEXT.
You can define the variable TableName as global so that you can use it in all the functions, like insert_data().
Use string interpolation for the INSERT statement also.
import sqlite3
conn = sqlite3.connect("School")
print ("Database has been created")
TableName = ""
def create_table():
global TableName
TableName = input("Enter table name: ").strip()
tb_exists ="SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?"
if not conn.execute(tb_exists, (TableName,)).fetchone():
tb_create = f"CREATE TABLE [{TableName}](ID INTEGER PRIMARY KEY, title TEXT, forename TEXT, surname TEXT)"
conn.execute(tb_create)
print("Table created successfully")
else:
print("Table Exists!")
def insert_data():
if len(TableName) > 0:
conn.execute(f"INSERT INTO [{TableName}] (ID,title,forename,surname) VALUES (234,'Mr','XXX','XXX')")
conn.commit()
create_table()
insert_data()
The name of the table, or of the columns cannot be parameterized, so you must build the query string. It means that you should control that the entered name is sane because building query from strings is know to be a vector for SQL injection.
But most (if not all) SQL database allow to create a table if it does not already exists. The syntax is just:
CREATE TABLE table_name IF NOT EXISTS (
column_name type,
...)
So here, you could just do:
import re
...
def create_table():
TableName = input("Enter table name: ")
# control name:
if not re.match(r'\w*$', TableName):
raise IllegalValue("Invalid table name")
tb_create =f"""CREATE TABLE {TableName} IF NOT EXISTS (ID INT PRIMARY KEY,title VARCHAR(10),
forename VARCHAR(20), surname VARCHAR(20))"""
conn.execute(tb_create)
I'm trying to move to SQLAlchemy from psycopg2. At a point in my code, I've got a list of column names in columnList to be created as text types in a table name stored in tableName. Using psycopg2, this query works as follows:
ct = 'CREATE TABLE ' + tableName + ' ( id integer PRIMARY KEY, '
for _col in columnList:
ct += '"' + _col + '" text, '
ct = ct[:-2] + ');'
cur.execute(ct)
conn.commit()
How can I achieve the same thing in SQLAlchemy, bearing in mind that I cannot hard code the column names or table names as they are drawn from a dynamic list?
Also, once this table is created, how should it and the columns be referenced later in the code when querying or inserting values?
Thanks.
Using this sample data:
data = {'table1name': ['textcol1', 'textcol2'],
'table2name': ['textcol3', 'textcol4']}
Here's one way to do it:
from sqlalchemy import Table, Column, Text, Integer, MetaData
metadata = MetaData()
for tblname, colnames in data.items():
Table(
tblname, metadata,
Column('id', Integer, primary_key=True),
*[Column(name, Text) for name in colnames]
)
The tables are automatically mapped to their name in the MetaData.tables dictionary...
print(type(metadata.tables['table1name'])) # <class 'sqlalchemy.sql.schema.Table'>
... so you can always access them through there to perform queries, as long as you have the name of the table.
This will render the create table statements:
from sqlalchemy.schema import CreateTable
for table in metadata.tables.values():
print(CreateTable(table))
Which prints:
CREATE TABLE table1name (
id INTEGER NOT NULL,
textcol1 TEXT,
textcol2 TEXT,
PRIMARY KEY (id) )
CREATE TABLE table2name (
id INTEGER NOT NULL,
textcol3 TEXT,
textcol4 TEXT,
PRIMARY KEY (id) )
I have a list of tuples like so:
>>> all_names = c.execute("""select name from fb_friends""")
>>> for name in all_names:
... print(name)
('Jody Ann Elizabeth Lill',)
('Georgia Gee Smith',)
...(282 more)...
('Josh Firth',)
('Danny Hallas',)
And I want to create a table for each individual person. First I need to replace all spaces with an underscore in order to be SQLite3 table names, so I do that like so:
>>> all_names = c.execute("""select name from fb_friends""")
>>> for name in all_names:
... friends_name = name[0].replace(" ", "_")
... print(friends_name)
Jody_Ann_Elizabeth_Lill
Georgia_Gee_Smith
...(282 more)...
Josh_Firth
Danny_Hallas
So if I understand correctly I now have a list, not a list of tuples..? Which should be simple to create all my tables from this list like so:
>>> all_names = c.execute("""select name from fb_friends""")
>>> for name in all_names:
... friends_name = name[0].replace(" ", "_")
... c.execute("""create table {0} (`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `work` TEXT NOT NULL, `education` TEXT, `current_city` TEXT, `phone_number` TEXT, `dob` TEXT, `gender` TEXT, `sexual_orientation` TEXT, `religion` TEXT, `relationship_status` TEXT, `about_me` TEXT )""".format(friends_name))
But all it does is create a table from the first name in the list, I would have thought the for loop would iterate over the list of names and create a table for each one, which is what I want, can people please advise me on a few things:
Is using the .replace method the best way to get the underscores in the names? If no then what is?
Why is the for loop not iterating over each name to create the tables? And how do I make it do that?
Are my methods correct at all? If not then what methods would do it better?
While your immediate issue is resolved likely due to the raw cursor not retrieving all records from database whereas cursor.fetchall() or list(cursor) imports all rows to client side (Python), a slight memory footprint but may ensure rows import in script, I would be remiss to not encourage best practices in database design.
As mentioned in comments, reconsider this approach and normalize your entire database model for one-to-many or many-to-many relationships between tables as relational databases are intended to do. This way you avoid the overhead, maintenance, and querying challenges of 280+ identically structured tables.
From your explanation, you sound like you need a distinct friends table with one-to-many links with workplaces and posts table and any others, all connected to a friendid as foreign keys. Ultimately, you would create tables only once and populate data with append queries:
-- CREATE TABLES
CREATE TABLE friends (
`friendid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`first_name` TEXT, last_name TEXT,
`work` TEXT, `education` TEXT,
`current_city` TEXT, `phone_number` TEXT,
`dob` TEXT, `gender` TEXT, `sexual_orientation` TEXT,
`religion` TEXT, `relationship_status` TEXT, `about_me` TEXT);
CREATE TABLE workplaces (
`workplaceid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`friendid` INTEGER,
`workplace` TEXT NOT NULL,
`city` TEXT, `state` TEXT);
CREATE TABLE posts (
`postid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`friendid` INTEGER,
`text` TEXT NOT NULL,
`postdate` TEXT, `postlocation` TEXT);
-- POPULATE TABLES (adjust to actual tables/fields)
INSERT INTO friends (first_name, last_name)
SELECT SUBSTR(`name`, 1, INSTR(`name`, " ")) AS first_name,
SUBSTR(`name`, INSTR(`name`, " ")+1) AS last_name,
FROM fb_friends;
INSERT INTO workplaces (friendid, work, city)
SELECT f.friendid, w.work, w.city
FROM fb_work w INNER JOIN friends f ON w.name = f.first_name & ' ' & f.last_name;
INSERT INTO posts (friendid, `text`, postdate)
SELECT f.friendid, p.post_text, p.post_date
FROM fb_posts p INNER JOIN friends f ON p.name = f.first_name & ' ' & f.last_name;
So after continually playing around with various methods I managed to figure out how to do this. In order to get the the code to work all that had to be done was to convert it to a list, like so:
>>> all_names = c.execute("""select name from fb_friends""")
>>> names = list(all_names) # I just added this line and changed the variable names below
>>> for name in names:
... friends_name = name[0].replace(" ", "_")
... c.execute("""create table {0} (`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `work` TEXT NOT NULL, `education` TEXT, `current_city` TEXT, `phone_number` TEXT, `dob` TEXT, `gender` TEXT, `sexual_orientation` TEXT, `religion` TEXT, `relationship_status` TEXT, `about_me` TEXT )""".format(name))
please try out this solution:
staff = ['a', 'b', 'c']
for name in staff:
c.execute("CREATE TABLE IF NOT EXISTS %s (name TEXT);" % (name))
I was playing around with sqlite in Python and trying to do some tutorials but when I try to create a table with a foreign key I get the "near "-": syntax error".
Here is my code
import sqlite3 as lite
conn = lite.connect("hospital.db")
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS Department(did INTEGER PRIMARY KEY AUTOINCREMENT, deptName TEXT)""")
c.execute("""CREATE TABLE IF NOT EXISTS Room(rid INTEGER PRIMARY KEY AUTOINCREMENT, nbBeds INT, nbEmptyBeds INT)""")
c.execute("""CREATE TABLE IF NOT EXISTS Patient(pid INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, lastname TEXT, address TEXT, telephone TEXT, e-mail TEXT, admitttanceDate TEXT, dischargeDate TEXT, FOREIGN KEY (roomId) REFERENCES Room(rid))""")
c.execute("""CREATE TABLE IF NOT EXISTS Employee(eid INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, lastname TEXT, address TEXT, telephone TEXT, e-mail TEXT, role TEXT, employmentStart TEXT, employmentEnd TEXT, employmentDays INT, FOREIGN KEY (patientId) REFERENCES Patient(pid), FOREIGN KEY(dept_id) REFERENCES Department(did))""")
conn.close()
I don't have any "-" character in any of my tables, so I do not understand what's wrong here.
e-mail is not a valid column identifier. Either put the name in double quotes, square brackets or backticks, or remove the -:
"e-mail" TEXT
[e-mail] TEXT
`e-mail` TEXT
email TEXT
should all work.