I' currently doing django from some video tutorial. I had difficult to figure out the line which forces to following error.
Validating models...
Unhandled exception in thread started by <bound method Command.inner_run of <django.contrib.staticfiles.management.commands.runserver.Command object at 0xb6e5722c>>
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/django/core/management/commands/runserver.py", line 88, in inner_run
self.validate(display_num_errors=True)
File "/usr/lib/python2.7/dist-packages/django/core/management/base.py", line 253, in validate
raise CommandError("One or more models did not validate:\n%s" % error_text)
django.core.management.base.CommandError: One or more models did not validate:
events.event: 'attendees' specifies an m2m relation through model Attendence, which has not been installed
I had include source code at bitbucket.
In models.ManyToManyField() of Event class I had put wrong name on through which causes the problem. Later I fixed it with correct class name and problem solved.
After correcting error model.py look like
...
class Event(models.Model): ##error
#"""docstring for Event"""
description = models.TextField()
creation_date = models.DateTimeField(default = datetime.now) #if you put the parenthesis on datetime.now every time changing the date called new function with different date and time
start_date = models.DateTimeField(null = True,blank = True)
creator = models.ForeignKey(User,related_name='event_creator_set')
attendees = models.ManyToManyField(User,through='Attendance') #error occurs due to wrong class name on through
latest = models.BooleanField(default = True)
objects = EventManager()
def __unicode__(self):
return self.description
def save(self,**kwargs):
Event.objects.today().filter(latest=True,
creator=self.creator).update(latest=False)
super(Event,self).save(**kwargs)
class Attendance(models.Model): ##error
user = models.ForeignKey(User)#,related_name='attendance_user_set')
event = models.ForeignKey(Event)#,related_name='attendance_event_set') ###error
registration_date = models.DateTimeField(default=datetime.now)
def __unicode__(self):
return "%s is attending %s" %(self.user.username,self.event)
...
Also Django syncdb error: One or more models did not validate suggested me to add related_name but excluding it don't cause any error so I hadn't include this.
Related
code:
query = Order.update(is_review=1, review_time=review_time).where(Order.order_sn == order_sn)
query.execute()
exception:
cursor = database.execute(self)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 2952, in execute
sql, params = ctx.sql(query).query()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 601, in sql
return obj.__sql__(self)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 2363, in __sql__
for k, v in sorted(self._update.items(), key=ctx.column_sort_key):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\peewee.py", line 555, in column_sort_key
return item[0].get_sort_key(self)
AttributeError: 'UnknownField' object has no attribute 'get_sort_key'
environment:
peewee version:3.9.5
python:3.7
I notice that you have posted this as a GitHub issue on the Peewee issue tracker as well. I've responded to your ticket and will paste my response here for anyone else:
You are clearly using models generated using the pwiz tool. If pwiz cannot determine the right field type to use for a column, it uses a placeholder "UnknownField". You will need to edit your model definitions and replace the UnknownField with an appropriate field type (e.g. TextField, IntegerField, whatever) if you wish to be able to use it in queries.
This seems like such a commonplace requirement, it'd be builtin, but anyway: If you have a model like the following one, how do you stop the eggs property being mutated after it's been set?
class Spam(ndb.Model):
eggs = ndb.StringProperty()
The goal is is to have the property not required, so it'd default to None, but once it's been mutated from None, to a string in the above case, it can never be changed again, but any insight into defining an immutable property would be appreciated.
I had considered using the validator argument of the ndb.Property to pass in a function; see the answers below for why that wouldn't work here. It's useful for understanding the objects and namespaces involved.
One approach which does not require you to use custom properties is to use hooks See docs https://developers.google.com/appengine/docs/python/ndb/modelclass#Model__post_get_hook
You would use a _post_get_hook(cls, key, future) and a _pre_put_hook(self)
In _post_get_hook you would store away the original value of the property
and in _pre_put_hook you would check that it is the same as the original value unless the original value is None.
ie
class Spam(ndb.Model):
eggs = ndb.StringProperty()
#classmethod
def _post_get_hook(cls,key,future):
obj = future.get_result()
obj._my_eggs_prop = obj.eggs
def _pre_put_hook(self):
if hasattr(self,'_my_eggs_prop'):
if self.eggs != self._my_eggs_prop:
if self._my_eggs_prop != None:
# do some logging.
raise ValueError
else:
setattr(self,'_my_eggs_prop',self.eggs)
# if the saved value doesn't exist, create it and store
# the value in case an update occurs after the initial put
# this also means the object was created and not get()
Here is an example of it working
s~lightning-catfish> import spam
s~lightning-catfish> x = spam.Spam(id='canned')
s~lightning-catfish> x.eggs = 'green'
s~lightning-catfish> x.put()
Key('Spam', 'canned')
s~lightning-catfish> y = x.key.get()
s~lightning-catfish> y._my_eggs_prop
u'green'
s~lightning-catfish> y.eggs = 'blue'
s~lightning-catfish> y.put()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 3232, in _put
return self._put_async(**ctx_options).get_result()
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 3247, in _put_async
self._pre_put_hook()
File "spam.py", line 18, in _pre_put_hook
raise ValueError
ValueError
The downside of this approach is you could change the property rely in it for some additional code and then only find out about it when you do the put. However that may not be so bad, as you should in theory not have any code that is modifying the property once changed. So you want to log, and track down how this could be occurring. Alternately you could reset the value to the original setting, but then you leave incorrect code in place.
A custom property takes a little more thought ;-)
Unfortunately you can't do what you want with a validator.
(prop,value) are the property instance and value to set. You don't have a handle in the validator for the instance of the class and therefore the pre-existing value. All the methods of the property you need to get the existing value need a model instance as an argument - like _has_value . The docs
Will be called with arguments (prop, value) and should either return
the (possibly coerced) value or raise an exception. Calling the
function again on a coerced value should not modify the value further.
(For example, returning value.strip() or value.lower() is fine, but
not value + '$'.) May also return None, which means "no change". See
also Writing Property Subclasses
`https://developers.google.com/appengine/docs/python/ndb/properties#options
You will need to write a custom property to manage the state of the value and prevent overwriting once set.
See the example below showing you that you haven't got access to the pre-existing value of the property and a validator isn't passed it or the instance of the model which would have the value.
s~lightning-catfish> from pdb import set_trace
s~lightning-catfish> def valid(prop,val):
... set_trace()
... return val
...
s~lightning-catfish> class X(ndb.Model):
... x = ndb.StringProperty(validator=valid)
...
s~lightning-catfish> y = X(x="abc")
> <console>(3)valid()
(Pdb) p prop
StringProperty('x', validator=<function valid at 0xaf2d02c>)
(Pdb) p prop._has_value
<bound method StringProperty._has_value of StringProperty('x', validator=<function valid at 0xaf2d02c>)>
(Pdb) p prop._has_value()
*** TypeError: TypeError('_has_value() takes at least 2 arguments (1 given)',)
(Pdb) c
s~lightning-catfish> y
X(x='abc')
I hope I didn't miss any topic that could answer my problem. I'm here now because I'm terribly frustrated and tired with the following task:
- I have a Spreasheet with Drive.Google with lots of data in it
- I would like to create an application with wxPython that would pull data from this spreeadsheet (in the most easy way possible)
- Would also like to get multiple data from a user who will access this application through a nice interface (panel aka window)
- The multiple data introduced by the user should be able to work with the data pulled out from the Spreasheet. For example to see if the data introduced by the user is in the Spreadsheet or not and also some other operations with the next data introduced by the user.
- Finally and most importantly show the results to the user (later I would also like to add some functions to save somehow the results)
I hope I managed to express clearly what I would like to do. Now I'm new to Google API's, Python adn wxPython, but I have experience with C++ , php, html .
I've spent 2 weeks now with discovering Drive.Google and learning Python and wxPython. I did follow all tuturials on these, made my notes, read tones of stackoverflow questions-answers, wiki.wxpython.org etc. I learn every single day and I can do now many things separately but to have all functions like I described above I just couldn't work out how to do. At least please orient me in the direction. Awfel lot of times I spend hours doing examples and getting nowhere. I have Python, wxPython extention, GoogleAppEngine Launcher and even pyCharm demo. Please be kind. This is my first question ever.
here's the mess I made so far combining relevant examples:
import wx
import gdata.docs
import gdata.docs.service
import gdata.spreadsheet.service
import re, os
class Form(wx.Panel):
def __init__(self, *args, **kwargs):
super(Form, self).__init__(*args, **kwargs)
self.createControls()
self.bindEvents()
self.doLayout()
self.spreasht()
def createControls(self):
self.logger = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_READONLY)
self.saveButton = wx.Button(self, label="Elvegzes")
self.nameLabel = wx.StaticText(self, label="type Name1:")
self.nameTextCtrl = wx.TextCtrl(self, value="type here")
self.name2Label = wx.StaticText(self, label="type Name2:")
self.name2TextCtrl = wx.TextCtrl(self, value="type here")
def bindEvents(self):
for control, event, handler in \
[(self.saveButton, wx.EVT_BUTTON, self.onSave),
(self.nameTextCtrl, wx.EVT_TEXT, self.onNameEntered),
(self.nameTextCtrl, wx.EVT_CHAR, self.onNameChanged)]:
control.Bind(event, handler)
def doLayout(self):
raise NotImplementedError
def spreadsht(self):
gd_client = gdata.spreadsheet.service.SpreadsheetsService()
gd_client.email = 'my email address'
gd_client.password = 'my password to it'
gd_client.source = 'payne.org-example-1'
gd_client.ProgrammaticLogin()
q = gdata.spreadsheet.service.DocumentQuery()
q['title'] = 'stationcenter'
q['title-exact'] = 'true'
feed = gd_client.GetSpreadsheetsFeed(query=q)
spreadsheet_id = feed.entry[0].id.text.rsplit('/',1)[1]
feed = gd_client.GetWorksheetsFeed(spreadsheet_id)
worksheet_id = feed.entry[0].id.text.rsplit('/',1)[1]
al1 = raw_input('Name1: ')
print al1
al2 = raw_input('Name2: ')
print al2
rows = gd_client.GetListFeed(spreadsheet_id, worksheet_id).entry
for row in rows:
for key in row.custom:
if al1 == row.custom[key].text:
print ' %s: %s' % (key, row.custom[key].text)
def onColorchanged(self, event):
self.__log('User wants color: %s'%self.colors[event.GetInt()])
def onReferrerEntered(self, event):
self.__log('User entered referrer: %s'%event.GetString())
def onSave(self,event):
self.__log('User clicked on button with id %d'%event.GetId())
def onNameEntered(self, event):
self.__log('User entered name: %s'%event.GetString())
def onNameChanged(self, event):
self.__log('User typed character: %d'%event.GetKeyCode())
event.Skip()
def onInsuranceChanged(self, event):
self.__log('User wants insurance: %s'%bool(event.Checked()))
# Helper method(s):
def __log(self, message):
''' Private method to append a string to the logger text
control. '''
self.logger.AppendText('%s\n'%message)
class FormWithSizer(Form):
def doLayout(self):
''' Layout the controls by means of sizers. '''
boxSizer = wx.BoxSizer(orient=wx.HORIZONTAL)
gridSizer = wx.FlexGridSizer(rows=5, cols=2, vgap=10, hgap=10)
# Prepare some reusable arguments for calling sizer.Add():
expandOption = dict(flag=wx.EXPAND)
noOptions = dict()
emptySpace = ((0, 0), noOptions)
# Add the controls to the sizers:
for control, options in \
[(self.nameLabel, noOptions),
(self.nameTextCtrl, expandOption),
(self.allomas2Label, noOptions),
(self.allomas2TextCtrl, expandOption),
emptySpace,
(self.saveButton, dict(flag=wx.ALIGN_CENTER))]:
gridSizer.Add(control, **options)
for control, options in \
[(gridSizer, dict(border=5, flag=wx.ALL)),
(self.logger, dict(border=5, flag=wx.ALL|wx.EXPAND,
proportion=1))]:
boxSizer.Add(control, **options)
self.SetSizerAndFit(boxSizer)
class FrameWithForms(wx.Frame):
def __init__(self, *args, **kwargs):
super(FrameWithForms, self).__init__(*args, **kwargs)
notebook = wx.Notebook(self)
form2 = FormWithSizer(notebook)
notebook.AddPage(form2, 'CALTH')
self.SetClientSize(notebook.GetBestSize())
if __name__ == '__main__':
app = wx.App(0)
frame = FrameWithForms(None, title='Relevant title˝')
frame.Show()
app.MainLoop()
THANK YOU AGAIN!!!!!!!!!!!
First, make sure you can download the data you want with just Python. Then create a wxPython GUI with a single button. In that button's handler, have it call the script that can download the data you want.
If that causes your GUI to become unresponsive, then you'll need to use a thread to do the downloading. I recommend the following articles if that's the case:
http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
http://wiki.wxpython.org/LongRunningTasks
Okay, so now you have the data downloading appropriately. Now you add a grid widget or a listctrl / object list view widget. Pick one of those. I prefer object list view, which you can read about here. Then in your button handler you can call your downloader script or thread and when that's done, you can load the widget with that data. If you're using a thread, then the thread will have to call the next step (i.e. the widget loading bit).
Now you should have your data displayed. All that's left is making it look pretty and maybe putting the downloading part into a menu item.
I have harvested data, its not particularly clean data, and this has been bulk uploaded into the DataStore. However I am getting the following issue when trying to simply loop through all the records. I don't much care about validation at this point as all I want to do is perform a bulk operation but GAE appears not to let me even loop through the data records. I want to get at the bottom of this. To my knowledge all records have data in the field for the country and I could switch of validation, but can someone explain why this is happening and GAE is being sensitive. Thanks
result = Company.all()
my_count = result.count()
if result:
for r in result:
self.response.out.write("hello")
The data model has these properties:
class Company(db.Model):
companyurl = db.LinkProperty(required=True)
companyname = db.StringProperty(required=True)
companydesc = db.TextProperty(required=True)
companyaddress = db.PostalAddressProperty(required=False)
companypostcode = db.StringProperty(required=False)
companyemail = db.EmailProperty(required=True)
companycountry = db.StringProperty(required=True)
The error message is below
Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 701, in __call__
handler.get(*groups)
File "/base/data/home/apps/XXX/1.358667163009710608/showcompanies.py", line 99, in get
for r in result:
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2312, in next
return self.__model_class.from_entity(self.__iterator.next())
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1441, in from_entity
return cls(None, _from_entity=entity, **entity_values)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 973, in __init__
prop.__set__(self, value)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 613, in __set__
value = self.validate(value)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2815, in validate
value = super(StringProperty, self).validate(value)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 640, in validate
raise BadValueError('Property %s is required' % self.name)
BadValueError: Property companycountry is required
If you have the bulk process you wish to run in its own script, you can construct a modified version of your Company class without validation. Since db.Model classes are just wrappers to the datastore based on the name of the class, you can have different classes in different parts of your code with different behaviors.
So you might have a model.py file with:
class Company(db.Model):
companyurl = db.LinkProperty(required=True)
# ...
companycountry = db.StringProperty(required=True)
# Normal operations go here
And, another bulk_process.py file with:
class Company(db.Model):
companyurl = db.LinkProperty()
# ...
companycountry = db.StringProperty()
result = Company.all()
my_count = result.count()
if result:
for r in result:
self.response.out.write("hello")
Because this second model class lacks the validation, it should run just fine. And, because the code is logically separated you don't have to worry about unintentional side-effects from removing the validation in the rest of your code. Just make sure that your bulk process doesn't accidentally write back data without validation (unless you're OK with this).
Following these instructions:
http://neogregious.blogspot.com/2011/04/migrating-app-to-high-replication.html
I have managed to migrate to the high replication datastore however I am now getting the following exception:
datastore_errors.BadArgumentError('ancestor argument should match app ("%r" != "%r")' %
(ancestor.app(), app))
The model data looks something like this:
class base_business(polymodel.PolyModel):
created = db.DateTimeProperty(auto_now_add=True)
class business(base_business):
some_data = db.StringProperty()
etc..
class business_image(db.Model):
image = db.BlobProperty(default=None)
mimetype = db.StringProperty()
comment = db.StringProperty(required=False)
# the image is associated like so
image_item = business_image(parent = business_item, etc... )
image_item.put()
The new app name has not been assigned to the ancestor model data. At the moment the data is returned however the logs are being populated with this exception message.
The actual stack trace using logging.exception:
2011-11-03 16:45:40.211
======= get_business_image exception [ancestor argument should match app ("'oldappname'" != "'s~newappname'")] =======
Traceback (most recent call last):
File "/base/data/home/apps/s~newappname/3.354412961756003398/oldappname/entities/views.py", line 82, in get_business_image
business_img = business_image.gql("WHERE ANCESTOR IS :ref_business and is_primary = True", ref_business = db.Key(business_key)).get()
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 2049, in get
results = self.fetch(1, config=config)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 2102, in fetch
raw = raw_query.Get(limit, offset, config=config)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1668, in Get
config=config, limit=limit, offset=offset, prefetch_size=limit))
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1600, in GetBatcher
return self.GetQuery().run(_GetConnection(), query_options)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1507, in GetQuery
order=self.GetOrder())
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 93, in positional_wrapper
return wrapped(*args, **kwds)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 1722, in init
ancestor=ancestor)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 93, in positional_wrapper
return wrapped(*args, **kwds)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 1561, in init
(ancestor.app(), app))
BadArgumentError: ancestor argument should match app ("'oldappname'" != "'s~newappname'")
Is there a way to manually set the app on the model data? Could I do something like this to resolve this?
if( ancestor.app() != app )
set_app('my_app')
put()
Before I do this or apply any other HACK is there something I should have done as part of the data migration?
This sort of error usually occurs because you're using fully qualified keys somewhere that have been stored in the datastore as strings (instead of ReferenceProperty), or outside the datastore, such as in URLs. You should be able to work around this by reconstructing any keys from external sources such that you ignore the App ID, something like this:
my_key = db.Key.from_path(*db.Key(my_key).to_path())