Why doent SQLite save inserted data? - python

I always have to keep the SQL Insert statement in my python code in order to read the data from the database. Doesn't keeping the SQL insert statement in the python code amount to inserting same data multiple times into the database? I think the data insertion statement should be run once to insert data once, after which the data should be readable from the database. Whenever I omit the data insertion statement from my code, I am not able to read the data from the database, as though the script has not been run before.
Can someone please help me understand why this happens?
Below is the code:
#!/usr/bin/python
import sqlite3
conn = sqlite3.connect('test.db')
print "Opened database successfully"
conn.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \ VALUES (1, 'Paul', 32, 'California', 20000.00 )")
conn.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \ VALUES (2, 'Allen', 25, 'Texas', 15000.00 )")

First point: you should use a cursor instead of calling connection.execute which is not part of the db-api2 standard.
So you want:
conn = sqlite3.connect('test.db')
c = conn.cursor()
c.execute(<your ssql statement here>)
Second point: nothing is really written to your db until you commit your transaction, so after your inserts you need :
conn.commit()
Note that all this is very clearly explained in the FineManual with a complete example, so please have mercy and read the doc before anything else.
Third point: your "test.db" file will be looked up (and eventually created if it does not exist) in whatever the current working directory is, so use an absolute path, always - because you cannot rely on where / how your script is called to be sure you're using the expected database.

Related

Heroku Database: Insert operation

I am confused while inserting data to my Postgres Database in heroku.
Here's the thing,
I have created connection to database, then
cursor = conn.cursor()
cursor.execute("INSERT INTO users(username, useremail, userpass) VALUES ('"+_name+"','"+_email+"','"+_password+"')")
After executing, I checked the sql status by
print(cursor.statusmessage)
it returns,
INSERT 0 1
but on executing, data =
cursor.fetchall()
it throws me error
File "/Users/abc/PycharmProjects/testSkillNetwork/app.py",
line 75, in signUp
data = cursor.fetchall().
ProgrammingError: no results to fetch
So, i am unable to understand why 'no results' when insertion is successful.
Any help will be appreciated. Thanks.
You need to issue a SELECT query in order to retrieve data from the database.
cursor.execute("SELECT * FROM users")
cursor.fetchall()
This should give you some results.
Also, you should commit the transaction once you have finished inserting data, otherwise it will be lost. Use:
conn.commit()
Another, bigger, issue is that the way that you construct your queries is vulnerable to SQL injection. Rather than using string concatenation you should use parameterised queries:
cursor.execute("INSERT INTO users(username, useremail, userpass) VALUES (%s, %s, %s)", (_name,_email,_password))
With this style the database adapter will substitute the place holders (%s) with the values from the tuple of arguments passed to cursor.execute(). Not only is this safer, it's a lot easier to read and maintain.
I am not sure what driver are you using to connect to the database, assuming you're using psycopg2, which is one of the most famous, what you're observing is a normal behaviour. Reading from here:
A ProgrammingError is raised if the previous call to execute*() did not produce any result set or no call was issued yet.
An insert statement produces no result, other that an error in case of failure. If you want to obtain the rows that you've just inserted, query the database again:
cur.execute("SELECT * FROM users;")
cur.fetchall()
and this will give you the rows.
Aside from this, if you read the basic usage and the section of parametrized queries, never use python string concatenation when executing your queries, because it makes it vulnerable to SQL injection attacks.

Bulk Insert into SQL Server with Python not working

I'm attempting to bulk insert a csv into a table in SQL server. The catch is, the data doesn't match the columns of the destination table. The destination table has several audit columns that are not found in the source file. The solution I found for this is to insert into a view instead. The code is pretty simple:
from sqlalchemy import create_engine
engine = create_engine('mssql+pyodbc://[DNS]')
conn = engine.connect()
sql = "BULK INSERT [table view] FROM '[source file path]' WITH (FIELDTERMINATOR = ',',ROWTERMINATOR = '\n')"
conn.execute(sql)
conn.close()
When I run the SQL statement inside of SSMS it works perfectly. When I try to execute it from inside a Python script, the script runs but no data winds up in the table. What am I missing?
Update: It turns out bulk inserting into a normal table doesn't work either.
Before closing the connection, you need to call commit() or the SQL actions will be rolled back on connection close.
conn.commit()
conn.close()
It turns out that instead of using SQL Alchemy, I had to use pypyodbc. Not sure why this worked and the other way didn't. Example code found here:How to Speed up with Bulk Insert to MS Server from Python with Pyodbc from CSV
This works for me after checking sqlalchemy transactions refeference. I don't explicitly set conn.commit() as
The block managed by each .begin() method has the behavior such that the transaction is committed when the block completes.
with engine.begin() as conn:
conn.execute(sql_bulk_insert)

inserting python variable data into sqlite table not saving

I'm querying a json on a website for data, then saving that data into a variable so I can put it into a sqlite table. I'm 2 out of 3 for what I'm trying to do, but the sqlite side is just mystifying. I'm able to request the data, from there I can verify that the variable has data when I test it with a print, but all of my sqlite stuff is failing. It's not even creating a table, much less updating the table (but it is printing all the results to the buffer for some reason) Any idea what I'm doing wrong here? Disclaimer: Bit of a python noob. I've successfully created test tables just copying the stuff off of the python sqlite doc
# this is requesting the data and seems to work
for ticket in zenpy.search("bananas"):
id = ticket.id
subj = ticket.subject
created = ticket.created_at
for comment in zenpy.tickets.comments(ticket.id):
body = comment.body
# connecting to sqlite db that exists. things seem to go awry here
conn = sqlite3.connect('example.db')
c = conn.cursor()
# Creating the table table (for some reason table is not being created at all)
c.execute('''CREATE TABLE tickets_test
(ticket id, ticket subject, creation date, body text)''')
# Inserting the variables into the sqlite table
c.execute("INSERT INTO ticketstest VALUES (id, subj, created, body)")
# committing changes the changes and closing
c.commit()
c.close()
I'm on Windows 64bit and using pycharm to do this.
Your table likely isn't created because you haven't committed yet, and your sql fails before it commits. It should work when you fix your 2nd sql statement.
You're not inserting the variables you've created into the table. You need to use parameters. There are two ways of parameterizing your sql statement. I'll show the named placeholders one:
c.execute("INSERT INTO ticketstest VALUES (:id, :subj, :created, :body)",
{'id':id, 'subj':subj, 'created':created, 'body':body}
)

Psycopg2: cursor.execute is not working properly

So, I have the following code that inserts the data of an old database to a new one:
...
cur_old.execute("""SELECT DISTINCT module FROM all_students_users_log_course266""")
module_rows = cur_old.fetchall()
for row in module_rows:
cur_new.execute("""INSERT INTO modules(label) SELECT %s WHERE NOT EXISTS (SELECT 1 FROM modules WHERE label=%s)""", (row[0], row[0]))
...
The last line executes a query where labels are inserted into the new database table. I tested this query on pgAdmin and it works as I want.
However, when execute the script, nothing is inserted on the modules table. (Actually the sequences are updated, but none data is stored on the table).
Do I need to do anything else after I call the execute method from the cursor?
(Ps. The script is running till the end without any errors)
You forgot to do connection.commit(). Any alteration in the database has to be followed by a commit on the connection. For example, the sqlite3 documentation states it clearly in the first example:
# Save (commit) the changes.
conn.commit()
And the first example in the psycopg2 documentation does the same:
# Make the changes to the database persistent
>>> conn.commit()
As Evert said, the commit() was missing. An alternative to always specifying it in your code is using the autocommit feature.
http://initd.org/psycopg/docs/connection.html#connection.autocommit
For example like this:
with psycopg2.connect("...") as dbconn:
dbconn.autocommit=True

MySQL rows delete when program exits

I'm using Python and MySQLdb to add rows to my database. It seems that when my script exits, the rows get deleted. My last lines before the script exits do a "select *" on the table, which shows my one row. When I re-run the script, the first lines (after opening the connection) do the same "select *" and return zero results. I'm really at a loss here. I've been working for about 2 hours on this, and can't understand what could be accessing my database.
Also, between running the scripts, I run the "select *" manually from a terminal with zero results.
If I manually add a row from the terminal, it seems to last.
The query to insert the row:
cursor.execute("INSERT INTO sessions(username, id, ip) VALUES (%s, %s, %s)", (username, SessionID, IP]))
The query I use to check the data:
cursor.execute("select * from sessions")
print cursor.fetchall()
This shows the row before the program exits, then shows nothing when the program is run again.
Thanks in advance for all the help.
Looks like you need to connection.commit() your changes after you execute the query (replace connection with your DB connection variable).
http://docs.python.org/library/sqlite3.html
Connection.commit():
This method commits the current transaction. If you don’t call this method, anything you did since the last call to commit() is not visible from other database connections. If you wonder why you don’t see the data you’ve written to the database, please check you didn’t forget to call this method.
Check this other question: Python MySQLdb update query fails
You can find some examples on how to commit, how to connect using autocommit, etc.

Categories

Resources