Please help....i am trying use solr, pysolr and haystack on my django site search. I have edited the haystack build_solr_schema script to use BaseCommand.add_argument(), removing the default options_list. Below are my versions used; Python 3.5.2 Django 1.11.11 solr-7.3.0 django-haystack 2.4.0 pysolr 3.7.0
# encoding: utf-8
from __future__ import absolute_import, division, print_function, unicode_literals
import sys
from optparse import make_option
from django.core.exceptions import ImproperlyConfigured
from django.core.management.base import BaseCommand
from django.template import Context, loader
from haystack import constants
from haystack.backends.solr_backend import SolrSearchBackend
class Command(BaseCommand):
help = "Generates a Solr schema that reflects the indexes."
def add_arguments(self, parser):
# positional arguments
parser.add_argument("-f", "--filename", action="store", type="string", dest="filename",
help='If provided, directs output to a file instead of stdout.',),
# optional positional arguments
parser.add_argument("-u", "--using", action="store", type="string", dest="using", default=constants.DEFAULT_ALIAS,
help='If provided, chooses a connection to work with.')
"""
base_options = (
make_option("-f", "--filename", action="store", type="string", dest="filename",
help='If provided, directs output to a file instead of stdout.'),
make_option("-u", "--using", action="store", type="string", dest="using", default=constants.DEFAULT_ALIAS,
help='If provided, chooses a connection to work with.'),
)
option_list = BaseCommand.option_list + base_options
"""
def handle(self, **options):
"""Generates a Solr schema that reflects the indexes."""
using = options.get('using')
schema_xml = self.build_template(using=using)
if options.get('filename'):
self.write_file(options.get('filename'), schema_xml)
else:
self.print_stdout(schema_xml)
def build_context(self, using):
from haystack import connections, connection_router
backend = connections[using].get_backend()
if not isinstance(backend, SolrSearchBackend):
raise ImproperlyConfigured("'%s' isn't configured as a SolrEngine)." % backend.connection_alias)
content_field_name, fields = backend.build_schema(connections[using].get_unified_index().all_searchfields())
return Context({
'content_field_name': content_field_name,
'fields': fields,
'default_operator': constants.DEFAULT_OPERATOR,
'ID': constants.ID,
'DJANGO_CT': constants.DJANGO_CT,
'DJANGO_ID': constants.DJANGO_ID,
})
def build_template(self, using):
t = loader.get_template('search_configuration/solr.xml')
c = self.build_context(using=using)
return t.render(c)
def print_stdout(self, schema_xml):
sys.stderr.write("\n")
sys.stderr.write("\n")
sys.stderr.write("\n")
sys.stderr.write("Save the following output to 'schema.xml' and place it in your Solr configuration directory.\n")
sys.stderr.write("--------------------------------------------------------------------------------------------\n")
sys.stderr.write("\n")
print(schema_xml)
def write_file(self, filename, schema_xml):
schema_file = open(filename, 'w')
schema_file.write(schema_xml)
schema_file.close()
The error is gives is given below as
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 275, in run_from_argv
parser = self.create_parser(argv[0], argv[1])
File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 249, in create_parser
self.add_arguments(parser)
File "/home/tochie/virtual_django/myblog_env/mysite/venv/lib/python3.5/site-packages/haystack/management/commands/build_solr_schema.py", line 22, in add_arguments
help='If provided, directs output to a file instead of stdout.',),
File "/usr/lib/python3.5/argparse.py", line 1344, in add_argument
raise ValueError('%r is not callable' % (type_func,))
ValueError: 'string' is not callable
Please help if there is any other way of solving this issue,without having to edit haystack's build_solr_schema or any other solution to this problem..Thanks
The problem is with the type
argument. As the name suggests, it needs to be the python type str
and not the python string 'string'
. Meaning this is what you need
def add_arguments(self, parser):
# positional arguments
parser.add_argument("-f", "--filename", action="store", type=str, dest="filename",
help='If provided, directs output to a file instead of stdout.', )
# optional positional arguments
parser.add_argument("-u", "--using", action="store", type=str, dest="using",
default=constants.DEFAULT_ALIAS, help='If provided, chooses a connection to work with.')
When you do pass type
as a string, and not the type str
, argparse
assumes you are supplying a callable for execution. See https://docs.python.org/3/library/argparse.html#type
type= can take any callable that takes a single string argument and returns the converted value:
def perfect_square(string):
value = int(string)
sqrt = math.sqrt(value)
if sqrt != int(sqrt):
msg = "%r is not a perfect square" % string
raise argparse.ArgumentTypeError(msg)
return value
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('foo', type=perfect_square)
parser.parse_args(['9'])
parser.parse_args(['7'])