SQLAlchemy simply doesn't update a row and it makes me crazy - sqlalchemy

I hope you are all ok!!! . Working on Sunday :O!!
I have the next DB named 'books' and a table named equally with the following structure:
id
title
author
pages
published
I am using SQLALCHEMY to update the title of row id==1, but it doesn't work. There is not errors just it executes normally.
engine = create_engine(config.DATABASE_URI)
Session = sessionmaker(bind=engine)
s= Session()
tabla_libros=meta.tables['books']
stmt= update(tabla_libros).values({'title':'futurehead'}).where(tabla_libros.c.id==1)
engine.execute(stmt)
s.commit()
It doesn't update the value on BD nor shows an error.
I appreciate some help thanks!!

I solved my question !!, As #snakecharmerb said as comment. The error is related to use session() AND engine.execute. The changes that I did with engine.execute() was reverted with session() because I did nothing with the last.
Thanks to all !! have a good day

Related

OPENQUERY SQL Server MYSQL UPDATE

I have to work on a linked server. My goal: Update an entire table in mysql server(version:8.0.21) via OPENQUERY in SQL Server(version 13.0.1742.0). I tried this but it generates an error Row cannot be located for updating. Some values may have been changed since it was last read and this one The rowset was using optimistic concurrency and the value of a column has been changed after the containing row was last fetched or resynchronized.
update linkedTable
set
linkedTable.id_parent=unlinkedTable.IdCat1,
linkedTable.code=unlinkedTable.CodeFamilleFAT,
linkedTable.niveau=unlinkedTable.NiveauCategorieFAT,
linkedTable.langue=unlinkedTable.CodeLangueFAT,
linkedTable.nom=unlinkedTable.LibelleCommercialFAT,
linkedTable.descriptionA=unlinkedTable.DescriptifCom1FAT,
linkedTable.vignette=null,
linkedTable.id_categorie=unlinkedTable.id
from openquery(NAMELINKEDSERVER, 'select id_categorie, id_parent, code, niveau, langue, nom, description as descriptionA, vignette from DatabaseMySQL.Table') as linkedTable
inner join DatabaseSQLserver.dbo.Table as unlinkedTable on unlinkedTable.Id = linkedTable.id_categorie
Then I tried this:
update linkedTable
set
linkedTable.id_parent=unlinkedTable.IdCat1,
linkedTable.code=unlinkedTable.CodeFamilleFAT,
linkedTable.niveau=unlinkedTable.NiveauCategorieFAT,
linkedTable.langue=unlinkedTable.CodeLangueFAT,
linkedTable.nom=unlinkedTable.LibelleCommercialFAT,
linkedTable.descriptionA=unlinkedTable.DescriptifCom1FAT,
linkedTable.vignette=null,
linkedTable.id_categorie=unlinkedTable.id
from openquery(NAMELINKEDSERVER, 'select id_categorie, id_parent, code, niveau, langue, nom, description as descriptionA, vignette from DatabaseMySQL.Table') as linkedTable
inner join DatabaseSQLserver.dbo.Table as unlinkedTable on unlinkedTable.Id = linkedTable.id_categorie
where linkedTable.id_categorie = 1
This work but only one row is updated. So I wrote a stored procedure to update each line but it took too much time.
Can someone explain why my first query didn't work (question1) and how I can reduce the time of my stored procedure (question2)?
I use while loop (count the number of id and update each id).
Thank you in advance.
Kind Regards.
I resolve the problem by checking some option on ODBC Driver in MySQL and reading some forum. I check this box.
enter image description here
This option allows to avoid the errors quoted previously. With this option, i can update multiple values without error on join or other request. Thank you Solarflare and "Another guy" (i lost the name) for correcting me (EDIT A POST). Have nice day both.

The cursor of pymysql fail to exercute SQL language

I would like to use pymysql to update the data in mysql database. But I don't know what's going wrong with my code.
IDEļ¼š pycharm
name1=input("enter the new one")
stu_ID=int(input("enter student ID"))
sql=f."UPDATE student SET name={name1} WHERE ID={stu_ID}"
cursor. execute(sql)
Since in your post is missing the error, i'm going to suppose that code is working fine but data are not updated at the end of the execution. If this assumption is not true, please add the error.
In your code is not present the declaration of database connection and from my point of viewm the problem could be there. In fact, for the update statement you should add parameter autocommit=True.
Check the following example:
database_connection=pymysql.connect(host=my_host,
user=my_user,
password=my_psw,
db=my_db_name,
charset=my_db_charset,
cursorclass=my_cursor_type,
autocommit=True)
This because pymysql starts an implicit transaction in case of update.
So in your case (without autocommit), at the end of the query execution, data are rollbacked.
Another different option, if you don't want add the autocommit in the database connection declaration is add an esplicit commit after the query like this:
database_connection.commit()

Rails 3: What is the best way to update a column in a very large table

I want to update all of a column in a table with over 2.2 million rows where the attribute is set to null. There is a Users table and a Posts table. Even though there is a column for num_posts in User, only about 70,000 users have that number populated; otherwise I have to query the db like so:
#num_posts = #user.posts.count
I want to use a migration to update the attributes and I'm not sure whether or not it's the best way to do it. Here is my migration file:
class UpdateNilPostCountInUsers < ActiveRecord::Migration
def up
nil_count = User.select(:id).where("num_posts IS NULL")
nil_count.each do |user|
user.update_attribute :num_posts, user.posts.count
end
end
def down
end
end
In my console, I ran a query on the first 10 rows where num_posts was null, and then used puts for each user.posts.count . The total time was 85.3ms for 10 rows, for an avg of 8.53ms. 8.53ms*2.2million rows is about 5.25 hours, and that's without updating any attributes. How do I know if my migration is running as expected? Is there a way to log to the console %complete? I really don't want to wait 5+ hours to find out it didn't do anything. Much appreciated.
EDIT:
Per Max's comment below, I abandoned the migration route and used find_each to solve the problem in batches. I solved the problem by writing the following code in the User model, which I successfully ran from the Rails console:
def self.update_post_count
nil_count = User.select(:id).where("num_posts IS NULL")
nil_count.find_each { |user|
user.update_column(:num_posts, user.posts.count) if user.posts
}
end
Thanks again for the help everyone!
desc 'Update User post cache counter'
task :update_cache_counter => :environment do
users = User.joins('LEFT OUTER JOIN "posts" ON "posts.user_id" = "users.id"')
.select('"users.id", "posts.id", COUNT("posts.id") AS "p_count"')
.where('"num_posts" IS NULL')
puts "Updating user post counts:"
users.find_each do |user|
print '.'
user.update_attribute(:num_posts, user.p_count)
end
end
First off don't use a migration for what is essentially a maintenance task. Migrations should mainly alter the schema of your database. Especially if it is long running like in this case and may fail midway resulting in a botched migration and problems with the database state.
Then you need to address the fact that calling user.posts is causing a N+1 query and you instead should join the posts table and select a count.
And without using batches you are likely to exhaust the servers memory quickly.
You can use update_all and subquery to do this.
sub_query = 'SELECT count(*) FROM `posts` WHERE `posts`.`user_id` = `users`.`id`'
User.where('num_posts IS NULL').update_all('num_posts = (#{sub_query})')
It will take only seconds instead of hours.
If so, you may not have to find a way to log something.

hibernate delete query not working when it is fired from my app

String query = DElETE from Photo where pId = :id and photoName = :name;
getSession().createQuery(query).setParameter("id", id)
.setParameter("name", name).executeUpdate();
The above does not work when it executes from my app. the query I got from this is,
delete from photo where id = 77 and photo_name = '77-Hollywood-Star.jpg';
i even used
createSQLQuery(delete from photo where id = 77 and photo_name = '77-Hollywood-Star.jpg';)
but no use!
The above works when I run this in mysql.
well then by the comment I understand you only needed to commit the transaction.
Remember that hibernate is pretty a complex framework, and if you don't use entity manager you have to manage transaction by your self!
Cheers
LG
I assume that above mentioned code was your actual code which you used for your testing purpose or whatsoever.I suspect their is some mismatch in your parameter names but not sure. can please post here your exception details?
Cheers!

MYSQL Search on Rails

Suppose that I do not have a certain id in mysql database. I am using rails, so the following code that I am using to query the database is the following...
#customer = Customer.find(params[:id])
How do I raise an exception of the ID does not exist? Please let me know :)
Thank you in advance!
When you call find on an ActiveRecord model it will automatically raise an ActiveRecord::RecordNotFound exception if the ID passed doesn't correspond to an existing record in the database. You can recover from this, but make sure you don't rely on this as expected flow (i.e. you don't want to do the above routine in a check on every page load, even when you don't know if params[:id] is even set).
def show
#customer = Customer.find params[:id]
rescue ActiveRecord::RecordNotFound
redirect_to customers_path
end
If the id does not exist your #customer will be nil.
raise Exception.new "SomeText" if #customer.nil?