Python Sqlite3 - Data get overwritten - python

When ever i try to insert data to my database, it's like it simply just overwrite whole file or not saving it correctly.
My thoughts about this script was that if i ran it multiple times it would output this:
(1, 126)
(2, 127)
(3, 126)
(4, 127)
I also now that if i doesn't create table within the script, it gives me an error that the table doesn't exist, even though the table was created, last time i ran the script.
import sqlite3
# Connecting to the database file
conn = sqlite3.connect("MyDB.db")
c = conn.cursor()
# Check if table exists
c.execute("DROP TABLE IF EXISTS t1")
# Create table
c.execute('''CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b INTEGER);''')
# Insert value
c.execute('''INSERT INTO t1 VALUES(NULL,126);''')
c.execute('''INSERT INTO t1 VALUES(NULL,127);''')
# Save changes
conn.commit()
for row in c.execute('SELECT * FROM t1'):
print(row)
# Output:
# (1, 126)
# (2, 127)
conn.close()
I really want this to work, since i'm working on a school project where my product is to make a functional store where you can add, remove products and sort them by date they were added.

Two issues:
You are dropping the table if exists, this will always deletes the table:
c.execute("DROP TABLE IF EXISTS t1")
You are re-creating the table after dropping:
c.execute('''CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b INTEGER);''')
You could comment above codes and re-run your script to get the output you want. But, in the final version ensure to check db and table exists before writing to it.

Related

UPDATE values of a column in a table with Python in SQL Server

I want to update a column with SQL server query in python, as you see I am updating the relative column as below:
I have a CSV file with some A values of relative table as below:
CSV file: (a.csv)
ART-B-C-ART0015-D-E01
ADC-B-C-ADC00112-V-E01
Python Code: (create Name Value)
ff = pd.read_csv("C:\\a.csv",encoding='cp1252')
ff["Name"]= df["A"].str.extract(r'([a-zA-Z]{3}\d{4,5})') + "-A"
Result of python Code:
ART0015-A
ADC00112-A
Table :
A Name FamilyName
ART-B-C-ART0015-D-E01 NULL ART
ADC-B-C-ADC00112-V-E01 NULL ADC00112
Also A is a column in my table (Not all of the A records but some of them) and based on A value I want to update Name column.
My database is SQL Server and I don't know how to update in Name Column in SQL Server where the A value in the csv file is equal to A in the relative table.
Code in Python:
conn = pyodbc.connect('Driver={SQL Server}; Server=ipaddress; Database=dbname; UID=username; PWD= {password};')
cursor = conn.cursor()
conn.commit()
for row in ff.itertuples():
cursor.execute('''UPDATE database.dbo.tablename SET Name where ?
)
conn.commit()
Expected result in table
A Name FamilyName
ART-B-C-ART0015-D-E01 ART0015-A ART
ADC-B-C-ADC00112-V-E01 ADC00112-A ADC00112
I would use an SQL temp table and inner join to update the values. This will work for only updating a subset of records in your SQL table. It can also be efficient at updating many records.
SQL Cursor
# reduce number of calls to server on inserts
cursor.fast_executemany = True
Create Temporary Table
statement = "CREATE TABLE #temp_tablename(A VARCHAR(200), Name VARCHAR(200))"
cursor.execute(statement)
Insert Values into a Temporary Table
# insert only the key and the updated values
subset = ff[['A','Name']]
# form SQL insert statement
columns = ", ".join(subset.columns)
values = '('+', '.join(['?']*len(subset.columns))+')'
# insert
statement = "INSERT INTO #temp_tablename ("+columns+") VALUES "+values
insert = [tuple(x) for x in subset.values]
cursor.executemany(statement, insert)
Update Values in Main Table from Temporary Table
statement = '''
UPDATE
tablename
SET
u.Name
FROM
tablename AS t
INNER JOIN
#temp_tablename AS u
ON
u.A=t.A;
'''
cursor.execute(statement)
Drop Temporary Table
cursor.execute("DROP TABLE #temp_tablename")

Insert error while inserting data to PostgreSQL with python psycopg2

try:
for i in (0, nCount):
query = "INSERT INTO students (Name, ID, Birth) VALUES (%s %d %d);"
data = ('Y', 2, 9)
cur.execute(query, data)
conn.commit()
except:
print("I can't INSERT into students")
Connect to database and select operation are work but insert operation is not.
I use PostgreSQL and pgAdmin4
And create database use pgAdmin4
The DB structure is Name(text), Id(integer), Birth(integer)
-------------------------------------------------------------------------
Solve
* Change type of all columns to text (not text[]).
* Change column name in DB to small letter.
From my best knowledge you missed , in values clause. I think you need write smthng like values (%s,%d,%d)

Python, insert XML data to sqlite3

Im trying to pull some XML from a URL, parse it and store the entries in an sqlite3 database, Im trying numerous things and all are failing. Codde so far:
#!/usr/bin/env python
from urllib2 import urlopen
import gc
import xml.etree.ElementTree as ET
import sqlite3
rosetta_url = ("https://boinc.bakerlab.org/rosetta/team_email_list.php?teamid=12575&account_key=Y&xml=1")
root = ET.parse(urlopen(rosetta_url)).getroot()
cpids = [el.text for el in root.findall('.//user/cpid')]
print cpids
conn = sqlite3.connect("GridcoinTeam.db")
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS GRIDCOINTEAM (cpid TEXT)''')
c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", cpids)
conn.commit()
conn.close()
conn = sqlite3.connect("GridcoinTeam.db")
c = conn.cursor()
cpids = c.execute('select cpid from GRIDCOINTEAM').fetchall()
conn.close()
print cpids
gc.collect()
Im getting the error:
Incorrect number of bindings supplied. The current statement uses 1, and there are 32 supplied.
I tried making the insertion tuples by changing to
c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", (cpids, ))
but that just gives:
Incorrect number of bindings supplied. The current statement uses 1, and there are 3289 supplied.
The XML extract is in the form ['5da243d1f47b7852d372c51d6ee660d7', '5a6d18b942518aca60833401e70b75b1', '527ab53f75164864b74a89f3db6986b8'], but there are several thousand entries.
Thanks.
You need to insert this as multiple rows instead of multiple columns into one row
cpids = [el.text for el in root.findall('.//user/cpid')]
cpids = zip(*[iter(cpids)]*1)
print cpids
The problem lies in
c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", cpids)
This executemany expects a list of tuples, but you pass a list of strings. What the code does effectively is:
for entry in cpids:
c.execute("INSERT INTO GRIDCOINTEAM VALUES (?);", *entry)
Note the star before entry, which unloads the string, and which gives you 32+ params whereas you only want one.
In order to fix that we'd need to know your GRIDCOINTEAM table schema. If you have a table with only one column and you want to insert that, you could probably do this:
for entry in cpids:
c.execute("INSERT INTO GRIDCOINTEAM VALUES (?)", entry)
In contrast to executemany, execute takes each parameter as one param - no tuples and lists unloading here.
Alternatively you can resort to using executemany, but you'd then need to wrap every one of your strings in a tuple or generator:
c.executemany("INSERT INTO GRIDCOINTEAM VALUES (?);", [(i,) for i in cpids])

Python SQLite3: want to iteratively fetching rows, but code is pulling every other row

I'm trying to accomplish a very simple task:
Create a table in SQLite
Insert several rows
Query a single column in the table and pull back each row
Code to create tab:
import sqlite3
sqlite_file = '/Users/User/Desktop/DB.sqlite'
conn = sqlite3.connect(sqlite_file)
c = conn.cursor()
c.execute('''CREATE TABLE ListIDTable(ID numeric, Day numeric, Month
numeric, MonthTxt text, Year numeric, ListID text, Quantity text)''')
values_to_insert = [
(1,16,7,"Jul",2015,"XXXXXXX1","Q2"),
(2,16,7,"Jul",2015,"XXXXXXX2","Q2"),
(3,14,7,"Jul",2015,"XXXXXXX3","Q1"),
(4,14,7,"Jul",2015,"XXXXXXX4","Q1")] #Entries continue similarly
c.executemany("INSERT INTO ListIdTable (ID, Day, Month, MonthTxt,
Year, ListID, Quantity) values (?,?,?,?,?,?,?)", values_to_insert)
conn.commit()
conn.close()
When I look at this table in SQLite DB Browser, everything looks fine.
Here's my code to try and query the above table:
import sqlite3
sqlite_file = '/Users/User/Desktop/DB.sqlite'
conn = sqlite3.connect(sqlite_file)
conn.row_factory = sqlite3.Row
c = conn.cursor()
for row in c.execute('select * from ListIDTable'):
r = c.fetchone()
ID = r['ID']
print (ID)
I should get a print out of 1, 2, 3, 4.
However, I only get 2 and 4.
My code actually uploads 100 entries to the table, but still, when I query, I only get ID printouts of even numbers (i.e. 2, 4, 6, 8 etc.).
Thanks for any advice on fixing this.
You don't need to fetchone in the loop -- The loop is already fetching the values (one at a time). If you fetchone while you're iterating, you'll only see half the data because the loop fetches one and then you immediately fetch the next one (without ever looking at the one that was fetched by the loop):
for r in c.execute('select * from ListIDTable'):
ID = r['ID']
print (ID)

SQLite3 serial type wasn't incremented

I was creating a database by using SQLite3.
and my python version is 2.7.5.
Before creating a database I simply created example database and tested it whether it will function well or not.
and It failed that the id wasn't incremented even I
declared it as a serial type.
I created simple database:
import sqlite3
con = sqlite3.connect('sample.db')
cur = con.cursor()
cur.execute("""CREATE TABLE sample(id serial,test real)""")
cur.execute("""INSERT INTO sample(test) VALUES(?)""",(3,))
cur.execute("""INSERT INTO sample(test) VALUES(?)""",(6,))
cur.execute("""INSERT INTO sample(test) VALUES(?)""",(8,))
con.commit()
Then I fetched all data:
data = cur.execute("""SELECT * from sample""")
t = data.fetchall()
In [33]: t
Out[33]: [(None, 3.0), (None, 6.0), (None, 8.0)]
I expected this:Out[33]: [(1, 3.0), (2, 6.0), (3, 8.0)]
However, As you can see, all of the id element was None
How can I solve this problem ?
I know I can do by just incrementing a variable and Insert it.
like this:
id += 1
cur.execute("""CREATE TABLE sample(id serial,test real)""")
id += 1
cur.execute("""INSERT INTO sample(test) VALUES(?)""",(3,))
id += 1
cur.execute("""INSERT INTO sample(test) VALUES(?)""",(6,))
However, isn't this awful ? I don't want to do it.
I'd like to make my code clear and smart.
There is no serial data type in SQLite. The correct way to create the table is with AUTOINCREMENT in SQLite:
CREATE TABLE sample ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
test REAL);
You'd need to mark a column as INTEGER PRIMARY KEY or INTEGER PRIMARY KEY AUTOINCREMENT to get auto-incrementation behaviour.
The difference between those two types is subtle; the latter form will never reuse IDs. See the ROWID and the INTEGER PRIMARY KEY documentation.

Categories

Resources