Python Sqlite, not able to print first line - python

Sqlite table structure:
id sno
1 100
2 200
3 300
4 400
conn=sqlite3.connect('test.sqlite')
c=conn.cursor()
c.execute("select * from abc")
mysel=c.execute("select * from abc where [id] = 1 ")
out put is:
1 100
its not printing id and sno i.e the First line of the table
how i can print First Line of table along with any kind of selection
please help

ID and sno are not data, they are part of your table structure (the column names).
If you want to get the names of the columns you need to do something like
connection = sqllite3.connect('test.sqlite')
cursor = connection.execute('select * from abc')
names = list(map(lambda x: x[0], cursor.description))

There isn't really a 'first line' containing the column names, that's just something the command line client prints out by default to help you read the returned records.
A dbapi2 conforming cursor has an attribute description, which is a list of tuples containing information about the data returned by the last query. The first element of each tuple will be the name of the column, so to print the column names, you can do something similar to:
c.execute("select * from abc")
print(tuple(d[0] for d in c.description))
for row in c:
print(row)
This will just print a tuple representation of the names and the records.

If you want to obtain details on the table you can use the following statement
PRAGMA table_info('[your table name]')
This will return a list of tuple with each tuple containing informations about a column
You will still have to add it to the data collected using the SELECT statement

When you write ... WHERE id = 1, you get only that particular record.
If you want to also get the first record, you have to tell SQLite that you want it:
SELECT id, sno FROM abc WHERE id = 'id'
UNION ALL
SELECT id, sno FROM abc WHERE id = 1
And when you already know what this particular subquery returns, you do not even need to bother with searching the table (and thus do not need to actually store the column names in the table):
SELECT 'id', 'sno'
UNION ALL
SELECT id, sno FROM abc WHERE id = 1

Related

SQLite AUTO_INCREMENT id field is upside down on the program

here a pic to a better understand
[1]: https://i.stack.imgur.com/S6tpl.png
def consult(self):
book = self.cuadro_blanco_cliente.get_children()
for elementos in book:
self.cuadro_blanco_cliente.delete(elementos)
query = "SELECT Nro, codigo, nombre, nfc, telefono, celular,direccion FROM clientes"#
rows = self.run_query(query)#query
for row in rows:
self.cuadro_blanco_cliente.insert('',0, text=row[1],values=row)
The problem isn't on the id field, is in the way you are using to add the rows on the display. You are traversing the array from id 1 to n, but adding the rows always to the beginning, making it look like the ids go from n to 1.
Try adding this at the end of your query clause:
"... ORDER BY id DESC"
This way, you will insert first, the last element, and then insert the other rows before the last, and so on, securing the fetched rows are ordered by id.
I added some lines to the code, and fixed the problem, begin from 1 now
for row in rows:
id = row[0]
self.cuadro_blanco_cliente.insert("",END, id, text=id, values=row)

python/mysql: SELECTing from multiple tables overwriting duplicate column in resulting dictionary

I am coding with Python 3.8.5, and mysql Ver 15.1 Distrib 10.4.11-MariaDB.
I have three tables, customer, partner and customer_partner,
customer has columns customer_id, customer_name, address;
partner has columns partner_id, partner_name, address; (note the address column appears in both tables, but obviously different content)
customer_partner has columns customer_id, partner_id, describing the partnership between one customer and one partner;
I am trying to fetch joined columns of customer and partner for customers whose customer_id is in a list with following python code and SQL statement:
db = connect(...)
cur = db.cursor(dictionary=True)
customer_id_tuple = (1, 2, 3)
sql = f"""SELECT *
FROM customer, partner, customer_partner
WHERE
customer.customer_id in ({','.join(['%s' for _ in range(len(customer_id_list))])})
AND customer.customer_id=customer_partner.customer_id
AND customer_partner.partner_id=partner.partner_id
"""
cur.execute(sql, customer_id_tuple))
data = cur.fetchall()
In the result dictionary data, I only see one address column. Obviously, address from partner table overwrites the one from customer table.
Besides modifying the column names, do I have a more decent way to avoid such overwriting behavior? Like automatically inserting the table name in front of the column name, like customer.address and partner.address?
SELECT * ... may lead to ambiguities when there are conflicting column names.
You should set aliases for conflicting column names.
Also set short aliases for the table names that can shorten the code and make it more readable and use them to qualify all the column names.
The implicit join syntax that you use has been replaced, since many years, by explicit join syntax.
Your code should be written like this:
sql = f"""
SELECT c.customer_id, c.customer_name, c.address customer_address,
p.partner_id, p.partner_name, p.address partner_address
FROM customer c
INNER JOIN customer_partner cp ON c.customer_id = cp.customer_id
INNER JOIN partner p ON cp.partner_id = p.partner_id
WHERE c.customer_id IN ({','.join(['%s' for _ in range(len(customer_id_list))])})
"""
I left out all the columns of customer_partner from the SELECT list because they are not needed.

Creating new column in database based upon user input/content in previous column

I'm making a database that takes user input and storing it in the database. However I want each row in the database (db) to be unique to each user and to contain separate input (thats the users put in)
This is the code I have so far:
user_id = random_number_genned_here
keyword = input_from_user
sqlite_file = 'keywords.sqlite'
conn = sqlite3.connect(sqlite_file)
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS keyword(userid TEXT UNIQUE, keyword TEXT)""")
try:
c.execute("""INSERT INTO keyword (userid , keyword) VALUES (?, ?, )""", (user_id,ukeyword))
except:
#where I need help
So basically what I need to do 2 things.
First thing: I need to see if a userid is already in the databse. The try and except does that. If it isn't in the database then I need to create a row in the database for that userid and add the keyword into the keyword column.
If a userid is already in the database then I need to add the keyword to the column.
Second thing: If the keyword column has some text in it, then I need to column to store the new keyword in.
I have bit and pieces of it but I don't know how to put it together.
To add a column to a table you can use the ALTER TABLE SQL
ALTER TABLE keyword ADD COLUMN your_column_definition
SQL As Understood By SQLite ALTER TABLE
You would have to generate the SQL programatically.
However, it would be simpler to look at the design of the keyword table. Why have the userid as UNIQUE when there are multiple data items to be stored per userid? I'd suggest that matters would be simplified if you were to have a composite UNIQUEness that is make userid and keyword combined as UNIQUE.
e.g. perhaps use :-
CREATE TABLE IF NOT EXISTS keyword(userid TEXT, keyword TEXT, UNIQUE(userid,keyword));
Perhaps consider the following demo :-
DROP TABLE IF EXISTS keyword;
CREATE TABLE IF NOT EXISTS keyword(userid TEXT, keyword TEXT, UNIQUE(userid,keyword));
INSERT OR IGNORE INTO keyword VALUES
('User001','TEST'),('User001','NOT A TEST'),('User001','KEYWORD A'),('User001','TEST'),
('User002','TEST'),('User002','KEYWORD A'),('User002','KEYWORD B')
;
-- Ooops (not really as duplicates just get ignored)
INSERT OR IGNORE INTO keyword VALUES
('User001','TEST'),('User001','NOT A TEST'),('User001','KEYWORD A'),('User001','TEST'),
('User002','TEST'),('User002','KEYWORD A'),('User002','KEYWORD B')
;
SELECT * FROM keyword;
SELECT * FROM keyword WHERE userid = 'User001';
When run the message log shows :-
DROP TABLE IF EXISTS keyword
> OK
> Time: 0.439s
CREATE TABLE IF NOT EXISTS keyword(userid TEXT, keyword TEXT, UNIQUE(userid,keyword))
> OK
> Time: 0.108s
INSERT OR IGNORE INTO keyword VALUES
('User001','TEST'),('User001','NOT A TEST'),('User001','KEYWORD A'),('User001','TEST'),
('User002','TEST'),('User002','KEYWORD A'),('User002','KEYWORD B')
> Affected rows: 6
> Time: 0.095s
-- Ooops (not really as duplicates just get ignored)
INSERT OR IGNORE INTO keyword VALUES
('User001','TEST'),('User001','NOT A TEST'),('User001','KEYWORD A'),('User001','TEST'),
('User002','TEST'),('User002','KEYWORD A'),('User002','KEYWORD B')
> Affected rows: 0
> Time: 0s
SELECT * FROM keyword
> OK
> Time: 0s
SELECT * FROM keyword WHERE userid = 'User001'
> OK
> Time: 0s
Note that the second insert inserts 0 rows as they are all duplicates
The queries produce :-

UPDATE query without hardcoding column names

Let's say mytable has 5 columns, id being the first one.
Is it possible to do an UPDATE without hardcoding the column names?
UPDATE mytable VALUES(4, "hello", 31.12, 4141.12, "gjhg") WHERE id = 4
I haven't found it in most tutorials.
Desired use case with sqlite3:
row = (4, "hello", 31.12, 4141.12, "gjhg")
c.execute('UPDATE mytable VALUES(?) WHERE id = ?', row, row[0])
As far as I know you cannot do that. According to https://sqlite.org/lang_update.html
However there are other ways of writing the query:
https://stackoverflow.com/a/13482298/7791653
You could generate a query yourself.
First you select all the column names and do a for loop where you build a String like "column1, column1, column1" and add that to the appropriate place of the query. All you have to do then is something like
"UPDATE users
SET (" + generatedQueryPart = ")
= ('value1', 'value2', 'value3')
WHERE some_condition ";
Hope this gave you some more information.

Get list of column names from a Firebird database table

How do you get a list of the column names in an specific table?
ie.
Firebird table:
| name | id | phone_number |
get list like this:
columnList = ['name', 'id', 'phone_number']
if you want to get a list of column names in an specific table, this is the sql query you need:
select rdb$field_name from rdb$relation_fields
where rdb$relation_name='YOUR-TABLE_NAME';
I tried this in firebird 2.5 and it works.
the single quotes around YOUR-TABLE-NAME are necessary btw
Get list of columns (comma-separated, order by position) for all table:
SELECT RDB$RELATION_NAME AS TABLE_NAME, list(trim(RDB$FIELD_NAME),',') AS COLUMNS
FROM RDB$RELATIONS
LEFT JOIN (SELECT * FROM RDB$RELATION_FIELDS ORDER BY RDB$FIELD_POSITION) USING (rdb$relation_name)
WHERE
(RDB$RELATIONS.RDB$SYSTEM_FLAG IS null OR RDB$RELATIONS.RDB$SYSTEM_FLAG = 0)
AND RDB$RELATIONS.rdb$view_blr IS null
GROUP BY RDB$RELATION_NAME
ORDER BY 1
Working well for check YOUR-COLUMN_NAME_fragment in database tables , used in DBeaver on FB 3.0.7
select
RDB$FIELD_NAME AS "COLUMN",
RDB$RELATION_NAME AS "TABLE"
from
rdb$relation_fields
where
RDB$FIELD_NAME like '%YOUR-COLUMN_NAME_fragment%';

Categories

Resources