MySQL / SQLite3 - mysql

I stumbled upon the following:
def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
bargain_id = 0
total_price = Decimal(0)
for instance in instances:
if isinstance(instance, BargainProduct):
total_price += instance.quantity * instance.product.price
bargain_id = instance.id
instance.save()
updateTotal = Bargain.objects.get(id=bargain_id)
updateTotal.total_price = total_price - updateTotal.discount_price
updateTotal.save()
This code is working for me on my local MySQL setup, however, on my live test enviroment running on SQLite3* I get the "Bargain matching query does not exist." error..
I am figuring this is due to a different hierarchy of saving the instances on SQLite.. however it seems they run(and should) act the same..?
*I cannot recompile MySQL with python support on my liveserver atm so thats a no go

Looking at the code, if you have no instances coming out of the formset.save(), bargain_id will be 0 when it gets down to the Bargain.objects.get(id=bargain_id) line, since it will skip over the for loop. If it is 0, I'm guessing it will fail with the error you are seeing.
You might want to check to see if the values are getting stored correctly in the database during your formset.save() and it is returning something back to instances.

This line is giving the error:
updateTotal = Bargain.objects.get(id=bargain_id)
which most probably is because of this line:
instances = formset.save(commit=False)
Did you define a save() method for the formset? Because it doesn't seen to have one built-in. You save it by accessing what formset.cleaned_data returns as the django docs say.
edit: I correct myself, it actually has a save() method based on this page.

I've been looking at this same issue. It is saving the data to the database, and the formset is filled. The problem is that the save on instances = formset.save(commit=False) doesn't return a value. When I look at the built-in save method, it should give back the saved data.
Another weird thing about this, is that it seems to work on my friends MySQL backend, but not on his SQLITE3 backend. Next to that it doesn't work on my MySQL backend.

Local loop returns these print outs (on MySQL).. on sqlite3 it fails with a does not excist on the query
('Formset: ', <django.forms.formsets.BargainProductFormFormSet object at 0x101fe3790>)
('Instances: ', [<BargainProduct: BargainProduct object>])
[18/Apr/2011 14:46:20] "POST /admin/shop/deal/add/ HTTP/1.1" 302 0

Related

Ruby `unless` not working

I am learning Ruby at the moment and I have written the below code, however it is causing errors when running.
The idea is that a channel will only be inserted in to the database if it is not already present in the database (checked via exists? method).
def exists?(channel)
rs = #con.query("SELECT * FROM channels WHERE name = #{channel}")
return true unless rs.empty?
end
channels.each do |channel|
#con.query("INSERT INTO channels (name, timestamp) VALUES ('#{channel}', '#{Time.now.to_i}')") unless channel.exists?
Here is an error message shown once I include this code:
undefined method `exists?' for "#channel1":String
Is there an error in the code that I've written?
I think you're confused about the syntax. If you want to use your above-defined method, you should have this:
#con.query("INSERT INTO channels (name, timestamp) VALUES ('#{channel}', '#{Time.now.to_i}')") unless exists?(channel)

Ruby MySQL output conflicting on different servers

I have coded a Ruby IRC bot which is on github (/ninjex/rubot) which is having some conflicting output with MySQL on a dedicated server I just purchased.
Firstly we have the connection to the database in the MySQL folder (in .gitignore) which looks similar to the following code block.
#con = Mysql.new('localhost', 'root', 'pword', 'db_name')
Then we have an actual function to query the database
def db_query
que = get_message # Grabs query from user i.e,./db_query SELECT * FROM words
results = #con.query(que) # Send query through the connection i.e, #con.query("SELECT * FROM WORDS")
results.each {|x| chan_send(x)} # For each row returned, send it to the channel via
end
On my local machine, when running the command:
./db_query SELECT amount, user from words WHERE user = 'Bob' and word = 'hello'
I receive the output in IRC in an Array like fashion: ["17", "Bob"] Where 17 is amount and Bob is the user.
However, using this same function on my dedicated server results in an output like: 17Bob I have attempted many changes in the code, as well as try to parse the data into it's own variable, however it seems that 17Bob is coming out as a single variable, making it impossible to parse into something like an array, which I could then use to send the data correctly.
This seems odd to me on both my local machine and the dedicated server, as I was expecting the output to first send 17 to the IRC and then Bob like:
17
Bob
For all the functions and source you can check my github /Ninjex/rubot, however you may need to install some gems.
A few notes:
Make sure you are sanitizing query via get_message. Or you are opening yourself up to some serious security problems.
Ensure you are using the same versions of the mysql gem, ruby and MySql. Differences in any of these may alter the expected output.
If you are at your wits end and are unable to resolve the underlying issue, you can always send a custom delimiter and use it to split. Unfortunately, it will muck up the case that is actually working and will need to be stripped out.
Here's how I would approach debugging the issue on the dedicated machine:
def db_query
que = get_sanitized_message
results = #con.query(que)
require 'pry'
binding.pry
results.each {|x| chan_send(x)}
end
Add the pry gem to your Gemfile, or gem install pry.
Update your code to use pry: see above
This will open up a pry console when the binding.pry line is hit and you can interrogate almost everything in your running application.
I would take a look at results and see if it's an array. Just type results in the console and it will print out the value. Also type out results.class. It's possible that query is returning some special result set object that is not an array, but that has a method to access the result array.
If results is an array, then the issue is most likely in chan_send. Perhaps it needs to be using something like puts vs print to ensure there's a new line after each message. Is it possible that you have different versions of your codebase deployed? I would also add a sleep 1 within the each block to ensure that this is not related to your handling of messages arriving at the same time.

Get Redmine custom field value to a file

I'm trying to create a text file that contains the value of a custom field I added on redmine. I tried to get it from an SQL query in the create method of the project_controller.rb (at line 80 on redmine 1.2.0) as follows :
sql = Mysql.new('localhost','root','pass','bitnami_redmine')
rq = sql.query("SELECT value
FROM custom_values
INNER JOIN projects
ON custom_values.customized_id=projects.id
WHERE custom_values.custom_field_id=7
AND projects.name='#{#project.name}'")
rq.each_hash { |h|
File.open('pleasework.txt', 'w') { |myfile|
myfile.write(h['value'])
}
}
sql.close
This works fine if I test it in a separate file (with an existing project name instead of #project.name) so it may be a syntax issue but I can't find what it is. I'd also be glad to hear any other solution to get that value.
Thanks !
(there's a very similar post here but none of the solutions actually worked)
First, you could use Project.connection.query instead of your own Mysql instance. Second, I would try to log the SQL RAILS_DEFAULT_LOGGER.info "SELECT ..." and check if it's ok... And the third, I would use identifier instead of name.
I ended up simply using params["project"]["custom_field_values"]["x"] where x is the custom field's id. I still don't know why the sql query didn't work but well, this is much simpler and faster.

Second RMySQL operation fails - why?

I am running a script that stores different datasets to a MySQL database. This works so far, but only sequentially. e.g.:
# write table1
replaceTable(con,tbl="table1",dframe=dframe1)
# write table2
replaceTable(con,tbl="table2",dframe=dframe2)
If I select both (I use StatET / Eclipse) and run the selection, I get an error:
Error in function (classes, fdef, mtable) :
unable to find an inherited method for function "dbWriteTable",
for signature "MySQLConnection", "data.frame", "data.frame".
I guess this has to do with the fact that my con is still busy or so when the second request is started. When I run the script line after line it just works fine. Hence I wonder, how can I tell R to wait til the first request is ready and then go ahead ? How can I make R scripts interactive (just console like plot examples - no tcl/tk).
EDIT:
require(RMySQL)
replaceTable <- function(con,tbl,dframe){
if(dbExistsTable(con,tbl)){
dbRemoveTable(con,tbl)
dbWriteTable(con,tbl,dframe)
cat("Existing database table updated / overwritten.")
}
else {
dbWriteTable(con,tbl,dframe)
cat("New database table created")
}
}
dbWriteTable has two important arguments:
overwrite: a logical specifying whether to overwrite an existing table
or not. Its default is ‘FALSE’.
append: a logical specifying whether to append to an existing table
in the DBMS. Its default is ‘FALSE’.
For past project I have successfully achieve appending, overwriting, creating, ... of tables with proper combinations of these.

Django modify DATABASE_HOST at runtime

I am trying to switch between 2 mysql servers at runtime. I do not need to maintain both connections alive all the time.
This is what I am doing
from django.conf import settings
from django.db import connection
from django.contrib.auth.models import User
connection.close()
setattr(settings, 'DATABASE_HOST', 'mysql1.com')
list1 = User.objects.all()
connection.close()
setattr(settings, 'DATABASE_HOST', 'mysql2.com')
list2 = User.objects.all()
I have the following settings.py:
DATABASE_HOST = '' # localhost
DATABASE_NAME = test
...
The database name is the same on all servers and only the content of each tables differ.
I should get list1 != list2 as the users are different on both servers.
The issue is that I always get the list of users from the default database defined in settings.py (which is running on localhost) instead of the one from mysql 1 server and then from mysql 2 server.
Any idea what I am doing wrong here?
Laurent
My guess, from the information, would be a potential error in your set DATABASE_HOST lines (in yor pseudo code above). read: "setattr(settings..."
Other than that, I'm not sure how you've configured your database to switch based on your criteria, as you've not explained this. If you are doing it by model, it may be worth considering how Django knows this, or even using external connections (manually loading the database driver and running commands by hand prior to the render stage), and using the main.
I'd query the whole approach, but mostly because I'm not sure how you're actually differentiating the two databases, or why. Could you provide a bit more information on how you're doing this? I assume the variables you're pulling in dot-points 2 and 5 above are different. I don't need the values, I'm just making sure you've not used the old code duplication and forgotten to edit it (we've all been there).
Note: I'd post this as a comment if I could, but I think the solution may be in how you're pulling the variables. Finally, you could try adding the database name (just the server IP or whatever) to the output, if you're in 'dev'/debug (offline/non-production) mode, to check if it's actually making it to the second server.
For reference, the Django documentation explicitly states you shouldn't do this -- Altering settings at runetime.
There is a lot of talk within the Django community about the ORM supporting multiple connections/databases at once. There's a lot of good reference info out there on it. Check out this blog post: Easy Multi-Database Support for Django and this Django wiki page Multiple Database Support.
In the blog post, Eric Florenzano does something like this in his settings.py file:
DATABASES = dict(
primary = dict(
DATABASE_NAME=DATABASE_NAME,
# ...
),
secondary = dict(
DATABASE_NAME='secondary.db',
# ...
),
)