def create_table(self, name: str, coulmn: str):
"""This method creates a table in the session.
Args:
name : Name of the table to be created.
coulmn : Column in the table to be created.
Format is "(name data_type condition, name2 data_type2 condition2...)".
"""
self.cur.execute(
query=SQL("CREATE TABLE {name} %s;").format(name=Identifier(name)),
vars=[coulmn]
)
This is method source code.
self.postgres.create_table(name="test", coulmn="(id serial PRIMARY KEY, name text)")
This is Test code.
psycopg2.errors.SyntaxError: 오류(error): 구문 오류(SyntaxError), "'(id serial PRIMARY KEY, name text)'" 부근(near)
LINE 1: CREATE TABLE "test" '(id serial PRIMARY KEY, name text)';
Why am I getting a syntax error?
A first run at this:
import psycopg2
from psycopg2 import sql
name = 'test'
columns = [('id', ' serial PRIMARY KEY,'), ('name', ' text')]
composed_cols = []
for col in columns:
composed_cols.append(sql.Composed([sql.Identifier(col[0]), sql.SQL(col[1])]))
[Composed([Identifier('id'), SQL(' serial PRIMARY KEY,')]),
Composed([Identifier('name'), SQL(' text')])]
qry = sql.SQL("CREATE TABLE {name} ({} {})").format(sql.SQL('').join(composed_cols[0]), sql.SQL('').join(composed_cols[1]), name=sql.Identifier(name))
print(qry.as_string(con))
CREATE TABLE "test" ("id" serial PRIMARY KEY, "name" text)
cur.execute(qry)
con.commit()
\d test
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+----------------------------------
id | integer | | not null | nextval('test_id_seq'::regclass)
name | text | | |
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
Basically break the column definition into two components, the name/identifier and the type/constraint portion. Then create a list that has these elements composed into the correct sql objects. Build the query string by joining the elements of the list into the {} placeholders for the column name and type/constraint portions respectively. Use named placeholder {name} for the table name. The portion that needs to be paid attention to is the sql.SQL as that is a literal string and if it is coming from an outside source it would need to be validated.
UPDATE
Realized this could be simplified as:
col_str = '(id serial PRIMARY KEY, name text)'
qry = sql.SQL("CREATE TABLE {name} {cols} ").format(cols=sql.SQL(col_str), name=sql.Identifier(name))
print(qry.as_string(con))
CREATE TABLE "test" (id serial PRIMARY KEY, name text)
Related
i have an sql insert query that take values from user input and also insert the ID from another table as foreign key. for this is write the below query but it seems not working.
Status_type table
CREATE TABLE status_type (
ID int(5) NOT NULL,
status varchar(50) NOT NULL
);
info table
CREATE TABLE info (
ID int(11) NOT NULL,
name varchar(50), NULL
nickname varchar(50), NULL
mother_name varchar(50), NULL
birthdate date, NULL
status_type int <==this must be the foreign key for the status_type table
create_date date
);
for the user he has a dropdownlist that retrieve the value from the status_type table in order to select the value that he want to insert into the new record in the info table
where as the info table take int Type because i want to store the ID of the status_type and not the value
code:
query = '''
INSERT INTO info (ID,name,nickname,mother_name,birthdate,t1.status_type,created_date)
VALUES(?,?,?,?,?,?,?)
select t2.ID
from info as t1
INNER JOIN status_type as t2
ON t2.ID = t1.status_type
'''
args = (ID,name,nickname,mother_name,db,status_type,current_date)
cursor = con.cursor()
cursor.execute(query,args)
con.commit()
st.success('Record added Successfully')
the status_type field take an INT type (the ID of the value from another table ).
So when the user insert it insert the value.
What i need is to convert this value into its corresponding ID and store the ID
based on the answer of #Mostafa NZ I modified my query and it becomes like below :
query = '''
INSERT INTO info (ID,name,nickname,mother_name,birthdate,status_type,created_date)
VALUES(?,?,?,?,?,(select status_type.ID
from status_type
where status = ?),?)
'''
args = (ID,name,nickname,mother_name,db,status_type,current_date)
cursor = con.cursor()
cursor.execute(query,args)
con.commit()
st.success('Record added Successfully')
When creating a record, you can do one of these ways.
Receive as input from the user
Specify a default value for the field
INSERT INTO (...) VALUES (? ,? ,1 ,? ,?)
Use a select in the INSERT
INSERT INTO (...) VALUES (? ,? ,(SELECT TOP 1 ID FROM status_type ODER BY ID) ,? ,?)
When INSERT data, you can only enter the names of the destination table fields. t1.status_type is wrong in the following line
INSERT INTO info (ID,name,nickname,mother_name,birthdate,t1.status_type,created_date)
What I want to do is create 4 interconnected progressive category classes.I don't know if the method I did is correct. Unfortunately I have been reading the document for days. but I haven't made much progress
Over the 'company' class how can I query all data belonging to the 'DepartmentalUnit' class?
create_table_company= '''CREATE TABLE company(
ID SERIAL PRIMARY KEY ,
NAME VARCHAR NOT NULL ,
); '''
create_table_department = '''CREATE TABLE department (
ID SERIAL PRIMARY KEY ,
NAME VARCHAR NOT NULL ,
company_id BIGINT,
FOREIGN KEY(company_id) REFERENCES COMPANY(id)); '''
create_table_department_unit = '''CREATE TABLE department_unit(
ID SERIAL PRIMARY KEY ,
NAME VARCHAR NOT NULL ,
department_id BIGINT,
FOREIGN KEY(department_id) REFERENCES DEPARTMENT(id));
create_table_department_unit_categroy = '''CREATE TABLE department_unit_category(
ID SERIAL PRIMARY KEY ,
NAME VARCHAR NOT NULL ,
department_unit_id BIGINT,
FOREIGN KEY(department_unit_id) REFERENCES DEPARTMENT_UNİT(id));
Something like this:
SELECT
c.id, c.name, du.*
FROM
company AS c
JOIN
department AS d
ON
c.id = d.company_id
JOIN
department_unit AS du
ON
du.department_id = d.id
;
UPDATE
The above query works to get the department_unit information by connecting the tables by their common fields. In this case the company table finds the department information for each company by using the company_id field in department that links back to a company. Once the departments for a company are found the department units for each department is found by using the department_id field in department_unit to link back to the department table. The end result is a chain that connects a company to its department units.
I am trying to parse a ddl statement using ddlparse. I am able to parse every field except Default parameter. I followed the below link.
https://github.com/shinichi-takii/ddlparse
Below is the ddl which i am trying to parse.
sample_ddl = """
CREATE TABLE My_Schema.Sample_Table (
Id integer PRIMARY KEY ,
Name varchar(100) NOT NULL DEFAULT 'BASANT',
Total bigint NOT NULL DEFAULT 1 ,
Avg decimal(5,1) NOT NULL,
Created_At date, -- Oracle 'DATE' -> BigQuery 'DATETIME'
UNIQUE (NAME)
);
"""
I can extract all information except DEFAULT parameter with below code :
for col in table.columns.values():
col_info = []
col_info.append("name = {}".format(col.name))
col_info.append("data_type = {}".format(col.data_type))
col_info.append("length = {}".format(col.length))
col_info.append("precision(=length) = {}".format(col.precision))
col_info.append("scale = {}".format(col.scale))
col_info.append("constraint = {}".format(col.constraint))
col_info.append("not_null = {}".format(col.not_null))
col_info.append("PK = {}".format(col.primary_key))
col_info.append("unique = {}".format(col.unique))
col_info.append("bq_legacy_data_type = {}".format(col.bigquery_legacy_data_type))
col_info.append("bq_standard_data_type = {}".format(col.bigquery_standard_data_type))
col_info.append("comment = '{}'".format(col.comment))
col_info.append("description(=comment) = '{}'".format(col.description))
col_info.append("BQ {}".format(col.to_bigquery_field()))
print(" : ".join(col_info))
Can anyone help me how to get the value for Default parameter?
Added supports to get the Default attribute in ddlparse v1.7.0.
for col in table.columns.values():
col_info = {}
col_info["default"] = col.default
print(json.dumps(col_info, indent=2, ensure_ascii=False))
The default constraint of your PRIMARY KEY does not make many sense. In the context of SQL Server you can create the following default constraint but it will not work:
DROP TABLE IF EXISTS dbo.Sample_Table
CREATE TABLE dbo.Sample_Table (
Id integer PRIMARY KEY DEFAULT 'BASANT',
Name varchar(100) NOT NULL, --COMMENT 'User name',
);
INSERT INTO dbo.Sample_Table (Name)
VALUES ('x')
Msg 245, Level 16, State 1, Line 9 Conversion failed when converting
the varchar value 'BASANT' to data type int.
Why? Because you can't set default value string to integer column.
And event if you said it to be number:
DROP TABLE IF EXISTS dbo.Sample_Table
CREATE TABLE dbo.Sample_Table (
Id integer PRIMARY KEY DEFAULT 1,
Name varchar(100) NOT NULL, --COMMENT 'User name',
);
INSERT INTO dbo.Sample_Table (Name)
VALUES ('x');
INSERT INTO dbo.Sample_Table (Name)
VALUES ('x');
It will work only the first time, the second you will get:
Msg 2627, Level 14, State 1, Line 23 Violation of PRIMARY KEY
constraint 'PK__Sample_T__3214EC0759729E5E'. Cannot insert duplicate
key in object 'dbo.Sample_Table'. The duplicate key value is (1).
because the primary key value must be unique. You may be looking for something like this:
ID INTEGER PRIMARY KEY IDENTITY(1,1)
I have two tables created from below query in SQLite:
CREATE TABLE people (
id integer unique primary key,
first_name text,
middle_name text,
last_name text,
email text,
phone text
);
CREATE TABLE companies (
id integer unique primary key,
name text,
url text,
contact integer,
FOREIGN KEY(contact) REFERENCES people(id)
);
I have all the data available in the first table, but I want to popup id in second table same as id in the first table.name in the companies table is concatenated string of first_name text,middle_name,last_name in people table.
I want something like "UPDATE companies SET contact = (SELECT people.id FROM people WHERE companies.name = people.first_name || "," || "people.second_name"; it will be great if I can show the string in people table is the subset of string in companies table
I am a beginner in python and SQlite both.
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 = '...')