Going off the documentation here.
I have this code:
from playhouse.flask_utils import FlaskDB,
app = Flask(__name__)
app.config.from_object(__name__)
flask_db = FlaskDB(app)
database = flask_db.database
class Item(flask_db.Model):
title = CharField()
content = TextField()
category = CharField()
#app.route('/create',methods=('GET','POST'))
def create():
if request.method == 'POST':
if request.form.get('title') and request.form.get('content'):
item = Item.create(
title = request.form['title'],
content = request.form['content'],
category = request.form['category'])
flash('Item created successfully','success')
return redirect(url_for('view'),item=item)
else:
flash('Title and Content are required.','danger')
form = ItemForm()
return render_template('create.html',form=form)
if __name__ == '__main__':
database.create_tables(Item)
app.run(debug=True)
They say it:
Dynamically create a Peewee database instance based on app config data.
However, I believe I still need to create the tables, in fact when I tried it without doing that second to last line, I could see that no tables existed in the created blog.db file. Unfortunately when I run this now, I get:
Traceback (most recent call last):
sqliteext:////Users/conduce-laptop/PycharmProjects/alexmarshall.website/blog.db
File "/Users/conduce-laptop/PycharmProjects/alexmarshall.website/website2.py", line 73, in <module>
database.create_tables(Item)
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 3855, in create_tables
create_model_tables(models, fail_silently=safe)
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 5293, in create_model_tables
for m in sort_models_topologically(models):
File "playhouse/_speedups.pyx", line 341, in playhouse._speedups.sort_models_topologically (playhouse/_speedups.c:7091)
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 4862, in __iter__
return iter(self.select())
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 3240, in __iter__
return iter(self.execute())
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 3233, in execute
self._qr = ResultWrapper(model_class, self._execute(), query_meta)
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 2912, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 3775, in execute_sql
self.commit()
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 3598, in __exit__
reraise(new_type, new_type(*exc_args), traceback)
File "/Users/conduce-laptop/anaconda2/lib/python2.7/site-packages/peewee.py", line 3768, in execute_sql
cursor.execute(sql, params or ())
peewee.OperationalError: no such table: item
You were invoking the create_tables incorrectly:
database.create_tables([Item], True)
The True allows you to call it multiple times without errors.
I had to run: Item.create_table(fail_silently=True) in in the very Bottom instead of database.create_tables(Item). Apparently you just run it once (since you wouldn't want to recreate the table
Related
I am trying to create an application in appengine that searches for a list of keys and then I use this list to delete these records from the datastore, this service has to be a generic service so I could not use a model just search by the name of kind, it is possible to do this through appengine features?
Below my code, but it requires that I have a model.
import httplib
import logging
from datetime import datetime, timedelta
import webapp2
from google.appengine.api import urlfetch
from google.appengine.ext import ndb
DEFAULT_PAGE_SIZE = 100000
DATE_PATTERN = "%Y-%m-%dT%H:%M:%S"
def get_date(amount):
date = datetime.today() - timedelta(days=30 * amount)
date = date.replace(hour=0, minute=0, second=0)
return date
class Purge(webapp2.RequestHandler):
def get(self):
kind = self.request.get('kind')
datefield = self.request.get('datefield')
amount = self.request.get('amount', default_value=3)
date = get_date(amount)
logging.info('Executando purge para Entity {}, mantendo periodo de {} meses.'.format(kind, amount))
# cria a query
query = ndb.Query(kind=kind, namespace='development')
logging.info('Setando o filtro [{} <= {}]'.format(datefield, date.strftime(DATE_PATTERN)))
# cria um filtro
query.filter(ndb.DateTimeProperty(datefield) <= date)
query.fetch_page(DEFAULT_PAGE_SIZE)
while True:
# executa a consulta
keys = query.fetch(keys_only=True)
logging.info('Encontrados {} {} a serem exluidos'.format(len(keys), kind))
# exclui usando as keys
ndb.delete_multi(keys)
if len(keys) < DEFAULT_PAGE_SIZE:
logging.info('Nao existem mais registros a serem excluidos')
break
app = webapp2.WSGIApplication(
[
('/cloud-datastore-purge', Purge),
], debug=True)
Trace
Traceback (most recent call last):
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/p~telefonica-dev-155211/cloud-datastore-purge-python:20180629t150020.410785498982375644/purge.py", line 38, in get
query.fetch_page(_DEFAULT_PAGE_SIZE)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/utils.py", line 160, in positional_wrapper
return wrapped(*args, **kwds)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 1362, in fetch_page
return self.fetch_page_async(page_size, **q_options).get_result()
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 383, in get_result
self.check_success()
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 427, in _help_tasklet_along
value = gen.throw(exc.__class__, exc, tb)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 1380, in _fetch_page_async
while (yield it.has_next_async()):
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 427, in _help_tasklet_along
value = gen.throw(exc.__class__, exc, tb)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 1793, in has_next_async
yield self._fut
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/context.py", line 890, in helper
batch, i, ent = yield inq.getq()
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 969, in run_to_queue
batch = yield rpc
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 513, in _on_rpc_completion
result = rpc.get_result()
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
return self.__get_result_hook(self)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/datastore/datastore_query.py", line 2951, in __query_result_hook
self.__results = self._process_results(query_result.result_list())
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/datastore/datastore_query.py", line 2984, in _process_results
for result in results]
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 194, in pb_to_query_result
return self.pb_to_entity(pb)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 690, in pb_to_entity
modelclass = Model._lookup_model(kind, self.default_model)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 3101, in _lookup_model
kind)
KindError: No model class found for kind 'Test'. Did you forget to import it?
The problem was found on the line where fetch_page is set.
Removing this line
query.fetch_page(DEFAULT_PAGE_SIZE)
for this
keys = query.fetch(limit=_DEFAULT_LIMIT, keys_only=True)
To run a datastore query without a model class available in the environment, you can use the google.appengine.api.datastore.Query class from the low-level datastore API.
See this question for other ideas.
If the goal is simply to wipe entities regardless of their kind then you have some options besides specifying the kinds/models yourself.
you could obtain the list of all kinds from your models file and iterate through them, see How to delete all the entries from google datastore?
using the generic datastore client library (not ndb) you could obtain the list of kinds from the datastore itself, see
Is there a way to delete all entities from a Datastore namespace Using Python3 (WITHOUT Dataflow)? But I vaguely remember some issues which might translate to that library not working on the 1st generation standard environment anymore, so I'm not 100% certain of this.
I was using peewee and threadpool for my project, my code is something like:
pool = threadpool.ThreadPool(10)
for city in city_list:
request = threadpool.WorkRequest(
clean_data_process, [city])
pool.putRequest(request)
pool.wait()
def clean_data_process(city):
data = Item.select().where(Item.city == city)
for item in data:
item.score = item.level + item.status
item.save()
Where Item here is my model.
class BaseModel(Model):
class Meta:
database = SqliteDatabase("test.db")
class Item(BaseModel):
city = CharField()
level = IntegerField()
status = IntegerField()
score = IntegerField()
And I got following error:
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/threadpool-1.3.2-py2.6.egg/threadpool.py", line 158, in run
result = request.callable(*request.args, **request.kwds)
File "/home/data_clean_convert.py", line 50, in clean_data_process
item.save()
File "/usr/lib/python2.6/site-packages/peewee.py", line 5166, in save
rows = self.update(**field_dict).where(self._pk_expr()).execute()
File "/usr/lib/python2.6/site-packages/peewee.py", line 3459, in execute
return self.database.rows_affected(self._execute())
File "/usr/lib/python2.6/site-packages/peewee.py", line 2940, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/usr/lib/python2.6/site-packages/peewee.py", line 3838, in execute_sql
self.commit()
File "/usr/lib/python2.6/site-packages/peewee.py", line 3657, in __exit__
reraise(new_type, new_type(*exc_args), traceback)
File "/usr/lib/python2.6/site-packages/peewee.py", line 3831, in execute_sql
cursor.execute(sql, params or ())
OperationalError: database is locked
Check out http://charlesleifer.com/blog/multi-threaded-sqlite-without-the-operationalerrors/ for some ideas -- you might try using wal-mode as the journalling mode.
I asked a question to try and fix an issue I was having where I didn't understand how to use ForeignKeys properly. That was very helpfully fixed, although I had a subsequent problem with django.db.utils.IntegrityError: core_team.blahblah_id may not be NULL and I decided to roll back, do something slightly simpler - in order to avoid a double lookup (Match is linked to both Team and League), I would write a management command to import the teams.
On my (clearly flawed) understanding from the previous question, I've done it right - it uses get_or_create to check for the league instance and then assigns the team based on that. I've also doublechecked that the DB is up to date (I'm running south and did the forward migration the last time I changed the scheme, nothing's changed since then. Last change was to make the names in both models the primary key (as there's only one team of each name, only one league of each name.)
Most recently, I've added code to provide the default to the team get_or_create section, but am receiving the same error. I understand the cause (I think) of the error - that the ForeignKey 'league' in Team already exists in the database, and can't be null inserting another team (from https://docs.djangoproject.com/en/1.5/ref/models/querysets/#get-or-create), just not how to fix it.
Management command:
from django.core.management.base import BaseCommand, CommandError
import csv
import csvImporter
#from core.models import Match
from time import strptime
from datetime import datetime
master_data = open ('/Users/chris/Desktop/AllDataTruncated.csv', 'r')
data = list(tuple(rec) for rec in csv.reader(master_data, delimiter=','))
from core.models import League, Team
team_list = []
for row in data:
if row[2] == "HomeTeam":
print "Continuing"
continue
elif row[2] == "":
print "Continuing"
continue
else:
league, _ = League.objects.get_or_create(name=row[0])
print league
team, _ = Team.objects.get_or_create(team_name=row[2], defaults={'league':league})
current_team = Team(league = league, team_name=team)
print current_team
And relevant bits of models.py:
class League (models.Model):
name = models.CharField(max_length=2, primary_key=True)
last_modified = models.CharField(max_length=50)
def __unicode__(self):
return unicode(self.name)
class Team(models.Model):
team_name = models.CharField(max_length=50, primary_key=True)
league = models.ForeignKey(League)
team_colour = models.CharField(max_length=6, null=True, blank=True)
def __unicode__(self):
return unicode (self.team_name)
The full traceback is:
$ python manage.py importteams
Continuing
E0
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 453, in execute_from_command_line
utility.execute()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 272, in fetch_command
klass = load_command_class(app_name, subcommand)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 77, in load_command_class
module = import_module('%s.management.commands.%s' % (app_name, name))
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/Users/chris/Dropbox/Django/gmblnew/core/management/commands/importteams.py", line 26, in <module>
team2, _ = Team.objects.get_or_create(team_name=row[3])
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/manager.py", line 146, in get_or_create
return self.get_query_set().get_or_create(**kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 487, in get_or_create
six.reraise(*exc_info)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 477, in get_or_create
obj.save(force_insert=True, using=self.db)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/base.py", line 546, in save
force_update=force_update, update_fields=update_fields)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/base.py", line 650, in save_base
result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/manager.py", line 215, in _insert
return insert_query(self.model, objs, fields, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 1661, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 937, in execute_sql
cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 364, in execute
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 362, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: core_team.league_id may not be NULL
Now - I think that it's odd that it's saying league_id here, as this shouldn't be relevant anymore? When I did the migration, the question came up:
? The field 'League.id' does not have a default specified, yet is NOT NULL.
? Since you are removing this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now.
? 2. Specify a one-off value to use for existing columns now
? 3. Disable the backwards migration by raising an exception; you can edit the migration to fix it later
? Please select a choice: 3
Is this what's perpetuating this issue?
Edit: Seems not. Dropped the DB and moved the South migrations folder, and it's still doing it. The source CSV is also fine (no blank lines or empty strings/segments), and the code above has a section to skip those segments anyway; it's not getting that far.
Ugh. The answer to this, for any other newbies who are coming to it later, is actually ludicrously simple. What I'm doing here is creating an entry in the table 'Team', which has a ForeignKey going back to 'League'.
The 'trick' (it's not a trick, just really badly explained in the documentation, imho) is that you need to explicitly pass the league back when you do the get_or_create for the Team object. It's not just about matching the team name
I thought I'd done this, but I hadn't, it appears. This code works (and quite effectively ensures there are no duplicates):
for row in data:
if row[2] == "HomeTeam":
print "Continuing"
continue
elif row[2] == "":
print "Continuing"
continue
else:
league, _ = League.objects.get_or_create(name=row[0])
print league
team, _ = Team.objects.get_or_create(team_name=row[2], league=league)
current_team = Team(league = league, team_name=team)
print current_team
All,
I have several custom fields on my models. I have tried adding "south_field_triple" methods on them in order to get db migration working. Initializing my application with south ("python manage.py convert_so_south myApp") works. But generating the first migration ("python manage.py schemamigration myApp --auto") fails with the following error:
TypeError: type() takes 1 or 3 arguments
The problem is occurring with the following field (I am not showing the code for the custom FormField or Widget; I assume those are not related to the cause of the problem):
class MyCustomField(models.CharField):
_type = "EnumerationField"
enumerationAppName = ""
enumerationModelName = ""
def __init__(self,*args,**kwargs):
enumeration = kwargs.pop('enumeration',None)
super(MyCustomField,self).__init__(*args,**kwargs)
if enumeration:
(self.enumerationAppName, self.enumerationModelName) = enumeration.split(".")
def getEnumeration(self):
try:
app = get_app(self.enumerationAppName)
enumeration = getattr(app,self.enumerationModelName)
return enumeration
except:
msg = "failed to get enumeration '%s.%s'" % (self.enumerationAppName,self.enumerationModelName)
print "error: %s" % msg
return None
def south_field_triple(self):
field_class_path = self.__class__.__module__ + "." + self.__class__.__name__
args,kwargs = introspector(self)
return (field_class_path,args,kwargs)
For what it's worth, this field presents the user with a set of choices. Those choices are defined in another class (specified by the "enumeration" argument to init). The FormField and Widget associated with this field use MultiValueField and MultiWidget, respectively, to present the user with a combo-box and a separate text box where the user can enter their own custom value not in the original enumeration. However, in the case of the model in the application being migrated - an enumeration is not provided.
Any ideas on what's gone wrong? Thanks.
edit: stacktrace added
File "manage.py", line 11, in <module>
execute_manager(settings)
File "/usr/local/lib/python2.7/site-packages/Django-1.4-py2.7.egg/django/core/management/__init__.py", line 459, in execute_manager
utility.execute()
File "/usr/local/lib/python2.7/site-packages/Django-1.4-py2.7.egg/django/core/management/__init__.py", line 382, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 196, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/site-packages/south/management/commands/schemamigration.py", line 97, in handle
old_orm = last_migration.orm(),
File "/usr/local/lib/python2.7/site-packages/south/utils.py", line 62, in method
value = function(self)
File "/usr/local/lib/python2.7/site-packages/south/migration/base.py", line 422, in orm
return FakeORM(self.migration_class(), self.app_label())
File "/usr/local/lib/python2.7/site-packages/south/orm.py", line 46, in FakeORM
_orm_cache[args] = _FakeORM(*args)
File "/usr/local/lib/python2.7/site-packages/south/orm.py", line 126, in __init__
self.models[name] = self.make_model(app_label, model_name, data)
File "/usr/local/lib/python2.7/site-packages/south/orm.py", line 320, in make_model
field = self.eval_in_context(code, app, extra_imports)
File "/usr/local/lib/python2.7/site-packages/south/orm.py", line 238, in eval_in_context
return eval(code, globals(), fake_locals)
File "<string>", line 1, in <module>
TypeError: type() takes 1 or 3 arguments
Aha! Turns out it was another custom field causing the problem; One that was created using a factory method.
class MyOtherCustomField(models.Field):
def __init__(self,*args,**kwargs):
super(MyOtherCustomField,self).__init__(**kwargs)
#classmethod
def Factory(cls,model_field_class_name,**kwargs):
try:
# there is a global dictionary of potential field_classes and extra kwargs to pass to the constructor
model_field_class_info = MODELFIELD_MAP[model_field_class_name.lower()]
model_field_class = model_field_class_info[0]
model_field_class_kwargs = model_field_class_info[1]
except KeyError:
msg = "unknown field type: '%s'" % model_field_class_name
print "error: %s" % msg
raise MyError(msg)
class _MyOtherCustomField(cls,model_field_class):
def __init__(self,*args,**kwargs):
kwargs.update(model_field_class_kwargs)
super(_MyOtherCustomField,self).__init__(**kwargs)
self._type = model_field_class_name
def south_field_triple(self):
# I was doing this which didn't work...
#field_class_path = self.__class__.__module__ + "." + self.__class__.__name__
# I'm now doing this which does work...
field_class_path = "django.db.models.fields" + "." + model_field_class.__name__
args,kwargs = introspector(self)
return (field_class_path,args,kwargs)
return _MyOtherCustomField(**kwargs)
I'm trying to create an admin user as part of my tests.py to check on persmissions.
UPDATE:
The tests.py is standard format that subclasses TestCase and the code below is called in the setUp() function.
I can create a normal user but not an admin user. If I try this:
self.adminuser = User.objects.create_user('admin', 'admin#test.com', 'pass')
self.adminuser.save()
self.adminuser.is_staff = True
self.adminuser.save()
OR
self.adminuser = User.objects.create_superuser('admin', 'admin#test.com', 'pass')
self.adminuser.save()
I get:
Warning: Data truncated for column 'name' at row 1
If I remove the is_staff line all is well (except I can't do my test!)
Do I have to load admin users as fixtures?
UserProfile is defined as follows:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
organisation = models.ForeignKey(Organisation, null=True, blank=True)
telephone = models.CharField(max_length=20, null=True, blank=True)
and full error traceback is:
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/test/testcases.py", line 242, in __call__
self._pre_setup()
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/test/testcases.py", line 217, in _pre_setup
self._fixture_setup()
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/test/testcases.py", line 440, in _fixture_setup
return super(TestCase, self)._fixture_setup()
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/test/testcases.py", line 222, in _fixture_setup
call_command('flush', verbosity=0, interactive=False)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/management/__init__.py", line 166, in call_command
return klass.execute(*args, **defaults)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/management/base.py", line 222, in execute
output = self.handle(*args, **options)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/management/base.py", line 351, in handle
return self.handle_noargs(**options)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/management/commands/flush.py", line 61, in handle_noargs
emit_post_sync_signal(models.get_models(), verbosity, interactive)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/management/sql.py", line 205, in emit_post_sync_signal
interactive=interactive)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/dispatch/dispatcher.py", line 166, in send
response = receiver(signal=self, sender=sender, **named)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/contrib/auth/management/__init__.py", line 28, in create_permissions
defaults={'name': name, 'content_type': ctype})
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/manager.py", line 123, in get_or_create
return self.get_query_set().get_or_create(**kwargs)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/query.py", line 335, in get_or_create
obj.save(force_insert=True)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/base.py", line 410, in save
self.save_base(force_insert=force_insert, force_update=force_update)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/base.py", line 495, in save_base
result = manager._insert(values, return_id=update_pk)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/manager.py", line 177, in _insert
return insert_query(self.model, values, **kwargs)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/query.py", line 1087, in insert_query
return query.execute_sql(return_id)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/sql/subqueries.py", line 320, in execute_sql
cursor = super(InsertQuery, self).execute_sql(None)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/models/sql/query.py", line 2369, in execute_sql
cursor.execute(sql, params)
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/db/backends/mysql/base.py", line 84, in execute
return self.cursor.execute(query, args)
File "build/bdist.linux-x86_64/egg/MySQLdb/cursors.py", line 175, in execute
File "build/bdist.linux-x86_64/egg/MySQLdb/cursors.py", line 89, in _warning_check
File "/usr/lib64/python2.4/warnings.py", line 61, in warn
warn_explicit(message, category, filename, lineno, module, registry)
File "/usr/lib64/python2.4/warnings.py", line 96, in warn_explicit
raise message
Warning: Data truncated for column 'name' at row 1
The answer seems to be that you can't create an admin user in setUp but you can in any other function so if you want an admin user in testing, use a fixture!
I'd use the built-in create_superuser and log the user in before making any requests. The following should work:
from django.contrib.auth.models import User
from django.test.client import Client
# store the password to login later
password = 'mypassword'
my_admin = User.objects.create_superuser('myuser', 'myemail#test.com', password)
c = Client()
# You'll need to log him in before you can send requests through the client
c.login(username=my_admin.username, password=password)
# tests go here
Update 2
Executed the snippet to create the superuser from within a test case (subclass of django.test.TestCase). Everything went fine. Also created and saved an instance of UserProfile with user = self.adminuser. That too worked.
Update
This line is interesting:
File "/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/contrib/auth/management/__init__.py", line 28, in create_permissions
defaults={'name': name, 'content_type': ctype})
Looks like execution fails when creating permissions.
Original Answer
Warning: Data truncated for column 'name' at row 1
Strange. I tried this from the Django shell and it worked for me. I am using Postgresql 8.3 and Django 1.2.1 on Ubuntu Jaunty. Can you give more details about which version of Django/database are you using?
Also User does not have a name attribute. Can you double check if you are using auth.User?
Do I have to load admin users as fixtures?
You don't have to. But if you are creating this admin user solely for testing purposes then it would be a good idea to add a Fixture. That is what I do in my projects.