Adding column in SQLite3, then filling it - python

I'm using SQLite 3.6, and connecting to it using Python 2.7 on Fedora 14.
I am attempting to add a column to a table using ALTER TABLE, then immediately afterwards UPDATE the table with data for the newly created column. Through python, I get nothing but NULLs in the database's new column. If I run the queries through sqlite3 in the terminal, it works.
Here is the--sanitized--python
def upgrade(cursor)
cursor.execute("ALTER TABLE Test ADD COLUMN 'Guid' TEXT")
cursor.execute("SELECT DISTINCT Name FROM Test WHERE ForeignKey=-1")
# Loop using a row factory that puts all the Names into a list called NameList
for Name in NameList:
Guid = uuid.uuid4()
cursor.execute("UPDATE Test SET Guid=? WHERE Name=?", (str(Guid),Name))
The SQLite3 connection is managed by the python's main function, and the connection is commited when the python script ends. The python executes without errors and debug statements show that all of the proper rows were found in the select call. However, when I look at the database using Sqliteman or sqlite3, I see only NULLs in the new column.
Here are my sqlite3 calls.
ALTER TABLE Test ADD COLUMN 'Guid' TEXT;
UPDATE Test SET GUID="foo" WHERE Name="Test3";
select Name, Guid from Test where Name='Test3';
This works for some reason. I see the--fake--guid where I expect.
I'm at my wits end for what to do.

The issue was in the main function, which exited before the connection's commit() call could be made due to an error in the main function.

Related

psycopg.errors.SyntaxError: syntax error at or near "ON" with execute

I'm using psycopg3 and PostgreSQL 14. When I run a copy or exec function, and include a ON argument, it gives me the error psycopg.errors.SyntaxError: syntax error at or near "ON"
I have tried two different functions, both resulting in the same error.
cur.execute("""
CREATE TABLE temp_mls AS TABLE mls_properties WITH NO DATA
ON COMMIT DROP
""")
and
cur.copy("""COPY mls_properties (fips_code") FROM STDIN
ON CONFLICT DO NOTHING
""")
No "CONFLICT" word in https://www.postgresql.org/docs/current/sql-copy.html.
Obviously, ON COMMIT DROP should warp in an transaction. However it only apply to temp table. Quote from manual:
ON COMMIT
The behavior of temporary tables at the end of a transaction block can be controlled using ON COMMIT. The three options are:
PRESERVE ROWS
No special action is taken at the ends of transactions. This is the default behavior.
DELETE ROWS
All rows in the temporary table will be deleted at the end of each transaction block. Essentially, an automatic TRUNCATE is done at
each commit.
DROP
The temporary table will be dropped at the end of the current transaction block.
So the following will work:
BEGIN;
CREATE temp TABLE temp_mls ON COMMIT DROP AS table test WITH NO DATA;
COMMIT;

How to get the data object of a newly inserted data row and flask-mysqldb?

I have work in Perl where I am able to get the newly created data object ID by passing the result back to a variable. For example:
my $data_obj = $schema->resultset('PersonTable')->create(\%psw_rec_hash);
Where the $data_obj contains the primary key's column value.
I want to be able to do the same thing using Python 3.7, Flask and flask-mysqldb,
but without having to do another query. I want to be able to use the specific
record's primary key column value for another method.
Python and flask-mysqldb inserts data like so:
query = "INSERT INTO PersonTable (fname, mname, lname) VALUES('Phil','','Vil')
cursor = db.connection.cursor()
cursor.execute(query)
db.connection.commit()
cursor.close()
The PersonTable has a primary key column called, id. So, the newly inserted data row would look
like:
23, 'Phil', 'Vil'
Because there are 22 rows of data before the last inserted data, I don't want to perform a search
for the data, because there could be more than one entry with the same data. However, all I want
the most recent data row.
Can I do something similar to Perl with python 3.7 and flask-mysqldb?
You may want to consider the Flask-SQLAlchemy package to help you with this.
Although the syntax is going to be slightly different from Perl, what you can do is, when you create the model object, you can set it to a variable. Then, when you either flush or commit on the Database session, you can pull up your primary key attribute on that model object you had created (whether it's "id" or something else), and use it as needed.
SQLAlchemy supports MySQL, as well as several other relational databases. In addition, it is able to help prevent SQL injection attacks so long as you use model objects and add/delete them to your database session, as opposed to straight SQL commands.

how to write sql to update some field given only one record in the target table

I got a table named test in MySQL database.
There are some fields in the test table, say, name.
However, there is only 0 or 1 record in the table.
When new record , say name = fox, comes, I'd like to update the targeted field of the table test.
I use python to handle MySQL and my question is how to write the sql.
PS. I try not to use where expression, but failed.
Suppose I've got the connection to the db, like the following:
conn = MySQLdb.connect(host=myhost, ...)
What you need here is a query which does the Merge kind of operation on your data. Algorithmically:
When record exists
do Update
Else
do Insert
You can go through this article to get a fair idea on doing things in this situation:
http://www.xaprb.com/blog/2006/06/17/3-ways-to-write-upsert-and-merge-queries-in-mysql/
What I personally recommend is the INSERT.. ON DUPLICATE KEY UPDATE
In your scenario, something like
INSERT INTO test (name)
VALUES ('fox')
ON DUPLICATE KEY UPDATE
name = 'fox';
Using this kind of a query you can handle the situation in one single shot.

pysqlite and python : wont insert data into table but code executes fine

I am trying to insert some data into a pysqlite database but even tho the code runs fine with no errors nothing shows up in the database and i have made sure that the variable does contain a value
cur = self.con.execute("insert into urllist(url) values('%s')" % seed)
i have double checked the table and column name and they are also correct
Are you calling con.commit() ?
Apparently changes are lost unless this method is used before closing the connection.
http://readthedocs.org/docs/pysqlite/en/latest/sqlite3.html

lastrowid() alternative or syntax without using execute in sqlite python?

In sqlite3 in python, I'm trying to make a program where the new row in the table to be written will be inserted next, needs to be printed out. But I just read the documentation here that an INSERT should be used in execute() statement. Problem is that the program I'm making asks the user for his/her information and the primary key ID will be assigned for the member as his/her ID number must be displayed. So in other words, the execute("INSERT") statement must not be executed first as the ID Keys would be wrong for the assignment of the member.
I first thought that lastrowid can be run without using execute("INSERT") but I noticed that it always gave me the value "None". Then I read the documentation in sqlite3 in python and googled alternatives to solve this problem.
I've read through google somewhere that SELECT last_insert_rowid() can be used but would it be alright to ask what is the syntax of it in python? I've tried coding it like this
NextID = con.execute("select last_insert_rowid()")
But it just gave me an cursor object output ""
I've also been thinking of just making another table where there will always only be one value. It will get the value of lastrowid of the main table whenever there is a new input of data in the main table. The value it gets will then be inserted and overwritten in another table so that every time there is a new set of data needs to be input in the main table and the next row ID is needed, it will just access the table with that one value.
Or is there an alternative and easier way of doing this?
Any help is very much appreciated bows deeply
You could guess the next ID if you would query your table before asking the user for his/her information with
SELECT MAX(ID) + 1 as NewID FROM DesiredTable.
Before inserting the new data (including the new ID), start a transaction,
only rollback if the insert failes (because another process was faster with the same operation) and ask your user again. If eveything is OK just do a commit.
Thanks for the answers and suggestions posted everyone but I ended up doing something like this:
#only to get the value of NextID to display
TempNick = "ThisIsADummyNickToBeDeleted"
cur.execute("insert into Members (Nick) values (?)", (TempNick, ))
NextID = cur.lastrowid
cur.execute("delete from Members where ID = ?", (NextID, ))
So basically, in order to get the lastrowid, I ended up inserting a Dummy data then after getting the value of the lastrowid, the dummy data will be deleted.
lastrowid
This read-only attribute provides the rowid of the last modified row. It is only set if you issued an INSERT statement using the execute() method. For operations other than INSERT or when executemany() is called, lastrowid is set to None.
from https://docs.python.org/2/library/sqlite3.html

Categories