Использование sqlite и Django

в разделе Программирование | Метки: Sqlite, Django

Создание каждой новой базы данных для нового веб-сайта на виртуальном хостинге довольно таки не дешевое занятие. Раньше при использовании Django я каждый раз заводил новую PosgreSQL базу, недавно зашел посмотрел во сколько мне это обходится, оказалось 841 рубль...
В связи с тем что мои сайты потребляют очень мало трафика использовать полноценные базы данных смысла просто нет. Судя по информации на wiki sqlite использование этой базы данных оправдано для сайтов с посещаемостью до 10000 хитов в сутки.

Все бы хорошо, да вот только использовать sqlite никак не получалось. Веб сервер и шелл с которого осуществляется управление - разные машины, директория веб-сервера подключена через NFS, python или django не могут работать через NFS. Создается файл sqlite базы (просто пустой файл), и записать туда ничего django не может. Проявляется это так:

$ python manage.py syncdb
Traceback (most recent call last):
  File "manage.py", line 11, in ?
    execute_manager(settings)
  File "/storage/home/username/python/lib/python2.4/site-packages/django/core/management/__init__.py", line 277, in execute_manager
    utility.execute()
  File "/storage/home/username/python/lib/python2.4/site-packages/django/core/management/__init__.py", line 225, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/storage/home/username/python/lib/python2.4/site-packages/django/core/management/base.py", line 70, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/storage/home/username/python/lib/python2.4/site-packages/django/core/management/base.py", line 84, in execute
    output = self.handle(*args, **options)
  File "/storage/home/username/python/lib/python2.4/site-packages/django/core/management/base.py", line 166, in handle
    return self.handle_noargs(**options)
  File "/storage/home/username/python/lib/python2.4/site-packages/django/core/management/commands/syncdb.py", line 47, in handle_noargs
    tables = [table_name_converter(name) for name in table_list()]
  File "/storage/home/username/python/lib/python2.4/site-packages/django/core/management/sql.py", line 14, in table_list
    return get_introspection_module().get_table_list(cursor)
  File "/storage/home/username/python/lib/python2.4/site-packages/django/db/backends/sqlite3/introspection.py", line 9, in get_table_list
    cursor.execute("""
  File "/home/username/python/lib/python2.4/site-packages/django/db/backends/sqlite3/base.py", line 133, in execute
    return Database.Cursor.execute(self, query, params)
pysqlite2.dbapi2.OperationalError: database is locked

Эту проблему я решил тем что скопировал файл с настройками и приложениями на свою локальную машину и там запустил python manage.py syncdb. После того как создалась база с минимально необходимыми данными (учетная запись и пр.) я положил этот файл обратно на хостинг. Дальше начались проблемы с установкой pysqlite:

$ python setup.py install --prefix /home/username/python
running install
running build
running build_py
creating build
creating build/lib.freebsd-6.2-STABLE-i386-2.4
creating build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2
copying pysqlite2/__init__.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2
copying pysqlite2/dbapi2.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2
creating build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/__init__.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/dbapi.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/factory.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/hooks.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/regression.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/transactions.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/types.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
copying pysqlite2/test/userfunctions.py -> build/lib.freebsd-6.2-STABLE-i386-2.4/pysqlite2/test
running build_ext
building 'pysqlite2._sqlite' extension
creating build/temp.freebsd-6.2-STABLE-i386-2.4
creating build/temp.freebsd-6.2-STABLE-i386-2.4/src
cc -fno-strict-aliasing -DNDEBUG -O2 -pipe -march=pentium4 -D__wchar_t=wchar_t -DTHREAD_STACK_SIZE=0x20000 -fPIC -DMODULE_NAME="pysqlite2.dbapi2" -I/usr/include -I/usr/local/include/python2.4 -c src/module.c -o build/temp.freebsd-6.2-STABLE-i386-2.4/src/module.o
In file included from src/module.c:24:
src/connection.h:33:21: sqlite3.h: No such file or directory
In file included from src/module.c:24:
src/connection.h:38: error: syntax error before "sqlite3"
In file included from src/module.c:25:
src/statement.h:37: error: syntax error before "sqlite3"
src/module.c:222: error: `SQLITE_OK' undeclared here (not in a function)
src/module.c:222: error: initializer element is not constant
src/module.c:222: error: (near initialization for `_int_constants[2].constant_value')
src/module.c:222: error: initializer element is not constant
src/module.c:222: error: (near initialization for `_int_constants[2]')
--------------порезано-----------------
src/module.c:249: error: `SQLITE_DETACH' undeclared here (not in a function)
src/module.c:249: error: initializer element is not constant
src/module.c:249: error: (near initialization for `_int_constants[29].constant_value')
src/module.c:249: error: initializer element is not constant
src/module.c:249: error: (near initialization for `_int_constants[29]')
src/module.c:257: error: initializer element is not constant
src/module.c:257: error: (near initialization for `_int_constants[30]')
src/module.c: In function `init_sqlite':
src/module.c:376: warning: passing arg 1 of `PyString_FromString' makes pointer from integer without a cast
error: command 'cc' failed with exit status 1

В FreeBSD все приложения как правило устанавливаются в /usr/local/ поэтому установочный скрипт искал необходимые ему библиотеки в /usr/lib/ а не в /usr/local/lib. Исправляется это в файле setup.cfg (лежит там же где и setup.py)

[build_ext]
define=
include_dirs=/usr/local/include
library_dirs=/usr/local/lib
libraries=sqlite3

после этого все нормально установилось. Однако и после этого ничего не заработало :)

[Sun Nov 25 06:13:35 2007] [error] [client 85.141.233.107] FastCGI: incomplete headers (0 bytes) received from server "/storage/home/username/website.com/dispatch.fcgi"
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr: Traceback (most recent call last):
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/flup/server/fcgi_base.py", line 558, in run
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     protocolStatus, appStatus = self.server.handler(self)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/flup/server/fcgi_base.py", line 1116, in handler
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     result = self.application(environ, start_response)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/core/handlers/wsgi.py", line 209, in __call__
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     response = middleware_method(request, response)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/contrib/sessions/middleware.py", line 37, in process_response
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     request.session.save()
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/contrib/sessions/backends/db.py", line 39, in save
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     Session.objects.create(
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/contrib/sessions/backends/base.py", line 101, in _get_session_key
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     self._session_key = self._get_new_session_key()
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/contrib/sessions/backends/base.py", line 93, in _get_new_session_key
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     if not self.exists(session_key):
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/contrib/sessions/backends/db.py", line 33, in exists
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     Session.objects.get(session_key=session_key)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/db/models/manager.py", line 69, in get
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     return self.get_query_set().get(*args, **kwargs)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/db/models/query.py", line 261, in get
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     obj_list = list(clone)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/db/models/query.py", line 114, in __iter__
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     return iter(self._get_data())
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/db/models/query.py", line 482, in _get_data
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     self._result_cache = list(self.iterator())
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/db/models/query.py", line 189, in iterator
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:   File "/home/username/python/lib/python2.4/site-packages/django/db/backends/sqlite3/base.py", line 133, in execute
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr:     return Database.Cursor.execute(self, query, params)
[Sun Nov 25 06:15:26 2007] [error] [client 85.141.233.107] FastCGI: server "/storage/home/username/website.com/dispatch.fcgi" stderr: OperationalError: no such table: django_session

Оказалось, что в файле settings.py (настройки django) необходимо прописывать полный путь к базе, то есть
DATABASE_NAME = '/home/username/django_projects/webproj/website.db'
а не
DATABASE_NAME = 'website.db'