Trying to let users update column values on existing records for a specific table named "Scenario." The record being updated is identified by an index column called "Scenario_Key", unique to each instance of this class. The code I already have produces a dictionary of key, value pairs where key is the name of the column being updated and value is the value being inserted into it. To update the sqlite database I'm trying the following:
cursor.execute("""UPDATE Scenario SET ?=? WHERE Scenario_Key=?;""", (key, new_val, self.scenario_key))
But when I try to execute by clicking the "Save and Close" button, I get the following:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1536, in __call__
return self.func(*args)
File "/Users/xxx/Documents/Consulting/DCA/Damage Control Assistant/EditScenarioWindow.py", line 91, in <lambda>
SaveAndCloseButton = Button(ButtonFrame, text="Save and Close", command=lambda: self.SaveAndCloseWindow())
File "/Users/xxx/Documents/Consulting/DCA/Damage Control Assistant/EditScenarioWindow.py", line 119, in SaveAndCloseWindow
cursor.execute(cmd_string, (key, new_val, self.scenario_key))
OperationalError: near "?": syntax error
I've read over sqlite3.OperationalError: near "?": syntax error, but I'm trying to do a single sqlite query where all the variables have already been calculated, not get values from the database and build a query from there. I'm supplying the positional arguments as a tuple. So why doesn't sqlite3 like the query I'm submitting?
You cannot parametrize column names. While being cognisant of the possibility of SQL Injection attacks, you could instead do:
cursor.execute("""UPDATE Scenario
SET {}=?
WHERE Scenario_Key=?;""".format(key),
(new_val, self.scenario_key))
Related
I am following this example to batch insert records into a table but modifying it to fit my specific example as such
sql='INSERT INTO CypressApp_grammatrix (name, row_num, col_num, gram_amount) VALUES {}'.format(', '.join(['(%s, %s, %s, %s)']*len(gram_matrix)),)
#print sql
params=[]
for gram in gram_matrix:
col_num=1
for g in gram:
params.extend([(matrix_name, row_num, col_num, g)])
col_num += 1
row_num += 1
print params
with closing(connection.cursor()) as cursor:
cursor.execute(sql, params)
However, upon doing so, I receive this error
return cursor._last_executed.decode('utf-8')
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/base.py", line 150, in __getattr__
return getattr(self.cursor, attr)
AttributeError: 'Cursor' object has no attribute '_last_executed'
I would like to know why I received this error and what I can do to fix it, although I feel the problem could be with this code that works with MySQL that I did not write
def last_executed_query(self, cursor, sql, params):
# With MySQLdb, cursor objects have an (undocumented) "_last_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
return cursor._last_executed.decode('utf-8')
So I don't know if I simply have an old copy of MySQLdb or what, but the problem appear to be with cursors.py. The only spot in that file where you can find _last_executed is here
def _do_query(self, q):
db = self._get_db()
self._last_executed = q
db.query(q)
self._do_get_result()
return self.rowcount
However, the __init__ does not set up this variable as an instance attribute. It's missing completely. So I took the liberty of adding it myself and initializing it to some query string. I assumed any would do, so I just added
class BaseCursor(object):
"""A base for Cursor classes. Useful attributes:
description
A tuple of DB API 7-tuples describing the columns in
the last executed query; see PEP-249 for details.
description_flags
Tuple of column flags for last query, one entry per column
in the result set. Values correspond to those in
MySQLdb.constants.FLAG. See MySQL documentation (C API)
for more information. Non-standard extension.
arraysize
default number of rows fetchmany() will fetch
"""
from _mysql_exceptions import MySQLError, Warning, Error, InterfaceError, \
DatabaseError, DataError, OperationalError, IntegrityError, \
InternalError, ProgrammingError, NotSupportedError
def __init__(self, connection):
from weakref import ref
...
self._last_executed ="SELECT * FROM T"
...
Now the cursor object does have the attribute _last_executed and when this function
def last_executed_query(self, cursor, sql, params):
# With MySQLdb, cursor objects have an (undocumented) "_last_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
return cursor._last_executed.decode('utf-8')
in base.py is called, the attribute does exist and so this error
return cursor._last_executed.decode('utf-8')
File "/usr/local/lib/python2.7/dist-
packages/django/db/backends/mysql/base.py", line 150, in __getattr__
return getattr(self.cursor, attr)
AttributeError: 'Cursor' object has no attribute '_last_executed'
will not be encountered. At least that is how I believe it works. In any case, it fixed the situation for me.
I have two questions about Django tracebacks.
First, if I have a traceback like the following, I can see that the error is occurring in the 'review_new_profile' view as shown in the second traceback error
below. Is it possible to tell Django to also display the line number in that view where the error occurred?
/srv/http/example.com/venvs/725be8a8537aeef8021231ba68de3184bbd547b1/local/lib/python2.7/site-packages/django/core/handlers/base.py in get_response
1. response = wrapped_callback(request, *callback_args, **callback_kwargs)
/srv/http/example.com/repo/profile/views.py in review_new_profile
1. user = User.objects.get(id=request.session['uid'])
/srv/http/example.com/venvs/725be8a8537aeef8021231ba68de3184bbd547b1/local/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py in __getitem__
1. return self._session[key]
What I'd like to see is something like the following where '540' is the line number in the views.py:
/srv/http/example.com/repo/profile/views.py in review_new_profile (540)
1. user = User.objects.get(id=request.session['uid'])
Second, am I correct in in thinking that the error actually occurred at the bottom-most line? So an interpretation of this trace is that Django was trying to generate a response to a request but when it tried to get a user instance for a given uid, it couldn't find the uid in the session? In other words, the error actually occurred on the last line in the traceback, where Django was trying to get the uid (key) from the session?
For your first question, Django does show the line. In your case, those 1s are the line numbers. The real question is why they are all 1s.
Second question: you are correct. The exception occurred on the last line.
Basically, when you did request.session['uid'], it tried to call that session object's __getitem__ method. Somewhere inside that __getitem__, there is this line:
return self._session[key]
This is what gave the error.
I am new to HDF5 file format and I have a data(images) saved in HDF5 format. The images are saved undere a group called 'data' which is under the root group as Carrays. what I want to do is to retrive a slice of the saved images. for example the first 400 or somthing like that. The following is what I did.
h5f = h5py.File('images.h5f', 'r')
image_grp= h5f['/data/'] #the image group (data) is opened
print(image_grp[0:400])
but I am getting the following error
Traceback (most recent call last):
File "fgf.py", line 32, in <module>
print(image_grp[0:40])
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
(/feedstock_root/build_artefacts/h5py_1496410723014/work/h5py-2.7.0/h5py/_objects.c:2846)
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
(/feedstock_root/build_artefacts/h5py_1496410723014/work/h5py
2.7.0/h5py/_objects.c:2804)
File "/..../python2.7/site-packages/h5py/_hl/group.py", line 169, in
__getitem__oid = h5o.open(self.id, self._e(name), lapl=self._lapl)
File "/..../python2.7/site-packages/h5py/_hl/base.py", line 133, in _e name = name.encode('ascii')
AttributeError: 'slice' object has no attribute 'encode'
I am not sure why I am getting this error but I am not even sure if I can slice the images which are saved as individual datasets.
I know this is an old question, but it is the first hit when searching for 'slice' object has no attribute 'encode' and it has no solution.
The error happens because the "group" is a group which does not have the encoding attribute. You are looking for the dataset element.
You need to find/know the key for the item that contains the dataset.
One suggestion is to list all keys in the group, and then guess which one it is:
print(list(image_grp.keys()))
This will give you the keys in the group.
A common case is that the first element is the image, so you can do this:
image_grp= h5f['/data/']
image= image_grp(image_grp.keys[0])
print(image[0:400])
yesterday I had a similar error and wrote this little piece of code to take my desired slice of h5py file.
import h5py
def h5py_slice(h5py_file, begin_index, end_index):
slice_list = []
with h5py.File(h5py_file, 'r') as f:
for i in range(begin_index, end_index):
slice_list.append(f[str(i)][...])
return slice_list
and it can be used like
the_desired_slice_list = h5py_slice('images.h5f', 0, 400)
Using Py2Neo 2.0 and Pycharm Community Edition 4
I'm trying to update a node. First I get the node object, change a node property, bind to the database, and then push the node. I get a slew of errors. Here is the code.
user_node = Graph().find_one('USER',
property_key='email',
property_value='marnee#marnee.com')
user_properties['mission_statement'] = 'New mission statement'
user_node.bind(uri=Graph().uri)
user_node.push()
The node is found, it does have a mission_statement property. The exception seems to happen on .push(). The Graph() uri is good, too.
Below are the errors.
I had been able to do this successfully about a week ago. I have not updated any packages recently.
The really weird part is that if I have a breakpoint and run this in debug mode I do not get any errors and the node is updated successfully.
Traceback (most recent call last):
File "C:/Users/Marnee Dearman/PycharmProjects/AgoraDev/py2neo_2.0_tests/create_rel_int_loc.py", line 27, in <module>
user_node.push()
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\core.py", line 1519, in push
batch.push()
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\batch\push.py", line 73, in push
self.graph.batch.run(self)
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\batch\core.py", line 99, in run
response = self.post(batch)
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\batch\core.py", line 88, in post
data.append(dict(job, id=i))
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\batch\core.py", line 232, in __iter__
yield "to", self.target.uri_string
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\batch\core.py", line 180, in uri_string
uri_string = self.entity.ref
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\core.py", line 1421, in ref
return "node/%s" % self._id
File "C:\Users\Marnee Dearman\PycharmProjects\VirtualEnvs\AgoraDev\lib\site-packages\py2neo\core.py", line 1412, in _id
self.__id = int(self.uri.path.segments[-1])
ValueError: invalid literal for int() with base 10: ''
Using Nigel's advice below, I got this to work. It was a usage error on my part:
user_node = Graph().find_one('USER',
property_key='email',
property_value='marnee#email.com')
user_node.properties['mission_statement'] = 'New mission statement'
user_node.push()
There are a couple of problems with your code so I will try to clarify the correct usage of these methods.
The bind method is used to connect a local entity (in this case, Node) to a corresponding remote equivalent. You should generally never need to use this method explicitly as entities are typically bound automatically on creation or retrieval. In your case, the find_one method does exactly this and constructs a client-side node that is bound to a corresponding server-side node; an explicit bind is not required.
The second issue is with your usage of bind. The URI taken by this method is that of a specific remote resource. You have passed the URI of the Graph itself (probably http://localhost:7474/db/data/) instead of that of the Node (such as http://localhost:7474/db/data/node/2345). The actual error that you see is caused by py2neo attempting to strip the ID from the URI and failing.
The simple solution is to remove the bind call.
Using pyscopg2, as Django database default backend, and with very simple case for a test. It fails trying to create a user, with a IntegrityError exception
$ python manage.py test project.core.tests
nosetests --verbosity 1 project.core.tests --rednose
Creating test database for alias 'default'...
X.
-----------------------------------------------------------------------------
1) ERROR: Tests that a user with a sha1 hashed password is change to newer hash method
Traceback (most recent call last):
crowddeals/core/tests.py line 7 in setUp
self.user1 = User.objects.create_user('user1', 'user1#domain.com')
env/lib/python2.7/site-packages/django/contrib/auth/models.py line 160 in create_user
user.save(using=self._db)
env/lib/python2.7/site-packages/django/db/models/base.py line 477 in save
force_update=force_update, update_fields=update_fields)
env/lib/python2.7/site-packages/django/db/models/base.py line 572 in save_base
result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
env/lib/python2.7/site-packages/django/db/models/manager.py line 203 in _insert
return insert_query(self.model, objs, fields, **kwargs)
env/lib/python2.7/site-packages/django/db/models/query.py line 1588 in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
env/lib/python2.7/site-packages/django/db/models/sql/compiler.py line 911 in execute_sql
cursor.execute(sql, params)
env/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py line 52 in execute
return self.cursor.execute(query, args)
IntegrityError: duplicate key value violates unique constraint "auth_user_pkey"
DETAIL: Key (id)=(1) already exists.
The default database is working, and is possible to add users. The tests fails just on the test database.
Looking at the test database, I see that the auto increment sequences for the primary keys for all tables has wrong start values, it takes the last used value from the default database as the start values on the test database.
For the default database, the User.id use the auto increment sequence.
CREATE SEQUENCE auth_user_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
And for the test database creates
CREATE SEQUENCE auth_user_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 2
CACHE 1;
This is obviously wrong, this happens also on other tables, as permissions.
CREATE SEQUENCE auth_permission_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 191
CACHE 1;
I can't guess why this is happening, it has to create the sequences on the new test database starting from 1.
If I change the database engine backend to sqlite3, the exception don't happen. This just happens in postgresql.
How can I fix this? so my tests can start working again.
If you don't recreate the db with every test, then you've have to reset the sequences yourself.
Also, I think that the sequence definition you've posted were found when inspecting the db after the tests run with a db tool. In that case, I think your db tool is presenting you the SQL to create the sequence as it is: after it's been used.
The fact that it doesn't happen on sqlite has to do with it using a in-memory db by default. Therefore, it's being re-created in every test run.