希望orm能加上 connect_args={'timeout': 15} 这种参数(for sqlite)的支持

35 views
Skip to first unread message

Chunlin Zhang

unread,
Aug 26, 2013, 2:40:34 AM8/26/13
to uli...@googlegroups.com
我这里一些web应用直接使用sqlite,而且现在不想换成其他的数据库
但有时候会出现data is locked这种错误,在代码里已经注意尽量缩小数据库的打开时间了

现在想试一下这里提到的解决方法:

"SQLAlchemy's create_engine() takes an argument connect_args which is a dictionary that will be passed to connect() of the underlying DBAPI (see Custom DBAPI connect() arguments).sqlite3.connect() accepts timeout argument, so this should work:
create_engine('sqlite:///some.db', connect_args={'timeout': 15})"

所以看能不能给 ORM.CONNECTIONS 加一个 CONNECT_ARGS 的参数,这样我能加上 timeout 的参数配置

limodou

unread,
Aug 26, 2013, 4:47:07 AM8/26/13
to uli...@googlegroups.com
从设计上,在settings.ini中配置的CONNECTION_ARGS会传给create_engine函数,见第216-217:

            args = c.get('connection_args', {})
            self.engine_instance = create_engine(c.get('connection_string'), **args)

所以你试一下就知道了。

CONNECTION_ARGS的处理在uliweb/contrib/orm/__init__.py中:

    d = {'connection_string':settings.get_var('ORM/CONNECTION'),
        'connection_type':settings.get_var('ORM/CONNECTION_TYPE'),
        'debug_log':settings.get_var('ORM/DEBUG_LOG'),
        'connection_args':settings.get_var('ORM/CONNECTION_ARGS'),
        'strategy':settings.get_var('ORM/STRATEGY'),
        }
    orm.engine_manager.add('default', d)
    
    for name, d in settings.get_var('ORM/CONNECTIONS').items():
        x = {'connection_string':d.get('CONNECTION', ''),
            'debug_log':d.get('DEBUG_LOG', None),
            'connection_args':d.get('CONNECTION_ARGS', {}),
            'strategy':d.get('STRATEGY', 'threadlocal'),
            'connection_type':d.get('CONNECTION_TYPE', 'long')
        }
        orm.engine_manager.add(name, x)



--
-- ----
Project : https://github.com/limodou/uliweb
doc : http://limodou.github.com/uliweb-doc
---
You received this message because you are subscribed to the Google Groups "Uliweb" group.
To unsubscribe from this group and stop receiving emails from it, send an email to uliweb+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: https://github.com/limodou/uliweb
My Blog: http://my.oschina.net/limodou

Chunlin Zhang

unread,
Aug 26, 2013, 5:32:21 AM8/26/13
to uli...@googlegroups.com
奇怪,我这里这么设的话
[ORM]
CONNECTIONS = {
    'default':{
        'CONNECTION':'sqlite:////home/fex/fex/database.db',
        'CONNECTION_ARGS':{'timeout': 8.0},
        'CONNECTION_TYPE':'short',
    }
}

报错了.
我去看sqlalchemy 里确实是有这个支持的啊(321行, sqlalchemy/lib/sqlalchemy/dialects/sqlite/pysqlite.py)
        opts = url.query.copy()
        util.coerce_kw_type(opts, 'timeout', float)

错误信息 :
Traceback (most recent call last):
  File "/usr/local/bin/uliweb", line 9, in <module>
    load_entry_point('Uliweb==0.1.7', 'console_scripts', 'uliweb')()
  File "/opt/www/uliweb/uliweb/manage.py", line 774, in main
    call()
  File "/opt/www/uliweb/uliweb/manage.py", line 771, in call
    execute_command_line(args or sys.argv, get_commands, 'uliweb', callback)
  File "/opt/www/uliweb/uliweb/core/commands.py", line 354, in execute_command_line
    m.execute(callback)
  File "/opt/www/uliweb/uliweb/core/commands.py", line 328, in execute
    cmd.run_from_argv(self.prog_name, subcommand, global_options, args[1:])
  File "/opt/www/uliweb/uliweb/core/commands.py", line 153, in run_from_argv
    self.execute(args, options, global_options)
  File "/opt/www/uliweb/uliweb/core/commands.py", line 175, in execute
    self.handle(options, global_options, *args)
  File "/opt/www/uliweb/uliweb/manage.py", line 522, in handle
    local_settings_file=global_options.local_settings)
  File "/opt/www/uliweb/uliweb/manage.py", line 96, in make_application
    **dispatcher_kwargs)
  File "/opt/www/uliweb/uliweb/core/SimpleFrame.py", line 361, in __init__
    self.init(project_dir, apps_dir)
  File "/opt/www/uliweb/uliweb/core/SimpleFrame.py", line 404, in init
    dispatch.call(self, 'after_init_apps')
  File "/opt/www/uliweb/uliweb/core/dispatch.py", line 104, in call
    _f(sender, *args, **kw)
  File "/opt/www/uliweb/uliweb/contrib/orm/__init__.py", line 39, in after_init_apps
    orm.engine_manager.add(name, x)
  File "/opt/www/uliweb/uliweb/orm/__init__.py", line 232, in add
    self.engines[name] = engine = NamedEngine(name, connection)
  File "/opt/www/uliweb/uliweb/orm/__init__.py", line 198, in __init__
    self.create()
  File "/opt/www/uliweb/uliweb/orm/__init__.py", line 206, in create
    self.engine_instance = create_engine(c.get('connection_string'), **args)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/__init__.py", line 338, in create_engine
    return strategy.create(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/strategies.py", line 142, in create
    engineclass.__name__))
TypeError: Invalid argument(s) 'timeout' sent to create_engine(), using configuration SQLiteDialect_pysqlite/NullPool/TLEngine.  Please check that the keyword arguments are appropriate for this combination of components.

limodou

unread,
Aug 26, 2013, 5:40:29 AM8/26/13
to uli...@googlegroups.com
回头我查一下。

limodou

unread,
Aug 26, 2013, 10:46:46 AM8/26/13
to uli...@googlegroups.com
我查了,它这块处理比较奇怪。

        opts = url.query.copy()
        util.coerce_kw_type(opts, 'timeout', float)
        util.coerce_kw_type(opts, 'isolation_level', str)
        util.coerce_kw_type(opts, 'detect_types', int)
        util.coerce_kw_type(opts, 'check_same_thread', bool)
        util.coerce_kw_type(opts, 'cached_statements', int)

这里opts首先会从url串中获得参数,然后coerce_ke_type的实现是:

def coerce_kw_type(kw, key, type_, flexi_bool=True):
    """If 'key' is present in dict 'kw', coerce its value to type 'type\_' if
    necessary.  If 'flexi_bool' is True, the string '0' is considered false
    when coercing to boolean.
    """

    if key in kw and type(kw[key]) is not type_ and kw[key] is not None:
        if type_ is bool and flexi_bool:
            kw[key] = asbool(kw[key])
        else:
            kw[key] = type_(kw[key])

它是必须key先要在参数中。所以,我理解如果url上没有这个参数,好象后面也不会生效。所以我把timeout不定义在CONNECTION_ARGS上,而是放在url上,如:

'CONNECTION':'sqlite:///database.db?timeout=8.0',

这样就可以了。

Chunlin Zhang

unread,
Aug 26, 2013, 10:04:55 PM8/26/13
to uli...@googlegroups.com
果然可以,用这个方法试试看

另外我要把这个讨论整理到wiki上,保存报错了:


local variable 'conflict' referenced before assignment

/usr/local/lib/python2.7/dist-packages/plugs-0.1.4-py2.7.egg/plugs/wiki/views.py in _wiki_edit, line 530

Traceback

A problem occurred in your Python WSGI application. Here is the sequence of function calls leading up to the error, in the order they occurred. Activate a code line to toggle context lines.

__call__ in /usr/local/lib/python2.7/dist-packages/Uliweb-0.2-py2.7.egg/uliweb/contrib/staticfiles/wsgi_staticfiles.py

[inspect]
91 return self.app(environ, start_response)

__call__ in /usr/local/lib/python2.7/dist-packages/Uliweb-0.2-py2.7.egg/uliweb/core/SimpleFrame.py

[inspect]
1129 response = self._open(environ)

_open in /usr/local/lib/python2.7/dist-packages/Uliweb-0.2-py2.7.egg/uliweb/core/SimpleFrame.py

[inspect]
1078 response = self.call_view(mod, handler_cls, handler, req, res, kwargs=values)

call_view in /usr/local/lib/python2.7/dist-packages/Uliweb-0.2-py2.7.egg/uliweb/core/SimpleFrame.py

[inspect]
717 result = self.call_handler(handler, request, response, env, wrap, args, kwargs)

call_handler in /usr/local/lib/python2.7/dist-packages/Uliweb-0.2-py2.7.egg/uliweb/core/SimpleFrame.py

[inspect]
803 result = self._call_function(handler, request, response, env, args, kwargs)

_call_function in /usr/local/lib/python2.7/dist-packages/Uliweb-0.2-py2.7.egg/uliweb/core/SimpleFrame.py

[inspect]
796 result = handler(*args, **kwargs)

wiki in /usr/local/lib/python2.7/dist-packages/plugs-0.1.4-py2.7.egg/plugs/wiki/views.py

[inspect]
351 return func(pagename)

_wiki_edit in /usr/local/lib/python2.7/dist-packages/plugs-0.1.4-py2.7.egg/plugs/wiki/views.py

[inspect]
530 return {'form':form, 'wiki':wiki, 'conflict':conflict}

Chunlin Zhang

unread,
Aug 26, 2013, 10:08:00 PM8/26/13
to uli...@googlegroups.com
果然可以,用这个方法试试看

另外我要把这个讨论整理到wiki上,保存的时候报错了:

limodou

unread,
Aug 27, 2013, 12:29:58 AM8/27/13
to uli...@googlegroups.com
wiki我看一下。

limodou

unread,
Aug 27, 2013, 12:42:21 AM8/27/13
to uli...@googlegroups.com
是有bug,不过如果不出错,好象还是可以保存的。就是出错时会有问题。

Chunlin Zhang

unread,
Aug 27, 2013, 1:39:43 AM8/27/13
to uli...@googlegroups.com
可是我这里必现啊
用附件内容保存每次都会出错
wiki.txt

limodou

unread,
Aug 27, 2013, 2:24:23 AM8/27/13
to uli...@googlegroups.com
现在不知道那个wiki是怎么回事?因为一保存报302,根本存不了。

limodou

unread,
Aug 27, 2013, 2:24:34 AM8/27/13
to uli...@googlegroups.com
我本地是好的。

limodou

unread,
Aug 27, 2013, 3:00:19 AM8/27/13
to uli...@googlegroups.com

Chunlin Zhang

unread,
Aug 27, 2013, 3:49:08 AM8/27/13
to uli...@googlegroups.com
果然可以了.另外一个小建议: html页面的title建议加上wiki的title

limodou

unread,
Aug 27, 2013, 3:57:51 AM8/27/13
to uli...@googlegroups.com
好的,我优化一下
Reply all
Reply to author
Forward
0 new messages