I'm having some trouble altering tables in my postgres database. I'm using psycopg2 and working out of Python. I tried to add a serial primary key. It took a long time (large table), and threw no error, so it did something, but when I went to check, the new column wasn't there.
I'm hoping this is something silly that I've missed, but right now I'm at a total loss.
import psycopg2
username = *****
password = *****
conn = psycopg2.connect(database='mydb',user=username,password=password)
query = "ALTER TABLE mytable ADD COLUMN sid serial PRIMARY KEY"
cur = conn.cursor()
cur.execute(query)
conn.close()
Other things I've tried while debugging:
It doesn't work when I remove PRIMARY KEY.
It doesn't work when try a different data type.
You need to add a commit statement in order for your changes to reflect in the table. Add this before you close the connection.
conn.commit()
Related
I'm attempting to insert data into my persons table. I've tried both by using a cursor in python cursor.execute(sql), and by connecting to the database with the terminal and inserting there. However, the program simply stops at the point of execution. I commit at the end. The table is empty and looks like this:
CREATE TABLE Persons(
AKey INT PRIMARY KEY, -- Person ID primary key
Name VARCHAR(128) UNIQUE NOT NULL, -- Person name
Website VARCHAR(256), -- URL for persons website
IKey INT REFERENCES Institutions -- Institution affiliation
);
And an example insert looks like this:
INSERT INTO persons (Akey, Name, Website, IKey) VALUES(1, 'John Smith', 'www.foo.bar', 1);
The insert is not made, nor does it produce an error. The terminal or python just stops at the insert statement, apparently not doing anything. Inserting into other tables works without any problems.
EDIT:
I should mention that I am the only one doing transactions on this database, which only contains empty tables.
It sounds like you are blocked on a lock. See Lock Monitoring. Some other session has done something which conflicts with yours, such as inserting a person with the same akey or name as you are trying to insert, or deleting the row from institutions which you are trying to reference, and that session has not committed. Now your session is waiting to see if that other one commits or rolls back.
I think you forget to commit your query.
A full example looks like this:
import contextlib
import psycopg2
db_config = dict(database="...", user="...", password="...")
with contextlib.closing(psycopg2.connect(**db_config)) as connection:
try:
with contextlib.closing(connection.cursor()) as cursor:
sql = "INSERT INTO persons (Akey, Name, Website, IKey) VALUES(1, 'John Smith', 'www.foo.bar', 1);"
cursor.execute(sql)
connection.commit()
except:
connection.rollback()
raise
I had no problem with SELECTing data in python from postgres database using cursor/execute. Just changed the sql to INSERT a row but nothing is inserted to DB. Can anyone let me know what should be modified? A little confused because everything is the same except for the sql statement.
<!-- language: python -->
#app.route("/addcontact")
def addcontact():
# this connection/cursor setting showed no problem so far
conn = pg.connect(conn_str)
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
sql = f"INSERT INTO jna (sid, phone, email) VALUES ('123','123','123')"
cur.execute(sql)
return redirect("/contacts")
first look at your table setup and make sure your variables are named right in the right order, format and all that, if your not logging into the specific database on the sql server it won't know where the table is, you might need to send something like 'USE databasename' before you do your insert statement so your computer is in the right place in the server.
I might not be up to date with the language but is that 'f' supposed to be right before the quotes? if thats in ur code that'd probably throw an error unless it has a use im not aware of or its not relevant to the problem.
You have to commit your transaction by adding the line below after execute(sql)
conn.commit()
Ref: Using INSERT with a PostgreSQL Database using Python
I wrote a python code that write/read data in/from a MySQL DB. The problem is that the table still empty even after I write in it. And when I close the program I loose all the data.
this is how I created the tables:
cursor.execute("CREATE TABLE IF NOT EXISTS employees (id INT UNSIGNED NOT NULL AUTO_INCREMENT,Name VARCHAR(20) NOT NULL,LastName VARCHAR(20) NOT NULL,Post VARCHAR(20) NOT NULL,RasID SMALLINT UNSIGNED NOT NULL,PRIMARY KEY (id)) ENGINE=INNODB;")
this is how I insert data in the tables:
cursor.execute("INSERT INTO employees VALUES (NULL, %s, %s, %s, %s);",(UserName, UserLastName, UserPost, int(data['RasID'])))
and this how I select data from the tables:
cursor.execute("SELECT * FROM employees WHERE Name= %s;",(Jmsg['face'],))
this what I get after inserting data in the table and the program still running:
mysql> select * from employees;
Empty set (0.00 sec)
NB: I can select data after inserting it when the program still running but as I mentioned the table is empty. So, is the code write in a temporary table or what?
Try
connection.commit()
MySQL Connector/Python, which you're probably using here, does not autocommit which means that you have do it manually to "push" changes to database.
You may want to commit after every execute but you may also try to run it sometimes to conserve your bandwidth (but then you risk that you lose your changes when something went wrong).
A transaction in a database takes generally no effect until it is commited.
I don't know about MySQL in Python, but I do know that sqlite3's Connection instances have a commit method, that will write the transaction into the database.
In addition, when working with sqlite3, closing the connection by calling Connection.close() or (by leaving a with block, I think) should write the current transaction.
But anyway, it's bad practice to leave an object that was opened open.
And by "bad practice", I mean "dangerous and prone to bugs".
Creating my table:
cursor.execute("""
CREATE TABLE if not exists intraday_quote (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
symbol VARCHAR(10) NOT NULL,
date DATE,
time DATE,
open FLOAT,
high FLOAT,
low FLOAT,
close FLOAT,
volume INTEGER);
""")
and I`m trying to insert this:
conn = sqlite3.connect('intraday_quote.db')
cursor = conn.cursor()
# Prepare SQL query to INSERT a record into the database.
sql = """INSERT INTO intraday_quote(symbol) VALUES ('Mac123432')"""
cursor.execute(sql)
No insertion happened in the database. What I am missing?
You need to commit your changes so they can get into effect in database.
commit all db operations like update, insert.
cursor.commit()
after your execute is succeeded. You can get return of the cursor.execute. If it is not None then you can try committing the changes else use rollback(exercise for you :) ) so you wont end up with wrong data updated in database.
You need to do conn.commit() to see the changes in the database. Quoting the documentation
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.
I have a table in my db called 'mytable'. I'd like to clear it so that I can continue to collect and analyze 'fresh data' from it.
Something like
conn = psycopg2.connect(database = mydb_name, host = mydb_server, user = mydb_uname, password = mydb_pwd)
cur = conn.cursor()
cur.execute("DROP TABLE mytable;")
Isn't going to work for me, because as far as I understand it, this destroys the table. I don't want to destroy/re-create... Just to flush all data.
How can I work this out?
Truncate tablename
Is useful for this, table stays just dropping the data!
If you have foreign keys you need to use the following
Truncate tablename CASCADE
For many tables do like this
Truncate table1, table2, table3
Your example
Cur.execute("truncate mytable;")
This sql query should delete all records from a table...
DELETE FROM mytable; // not DELETE * FROM mytable;