fixed issue with ordereddict in python < 2.7, added rname support also for fields
This commit is contained in:
+30
-19
@@ -172,10 +172,9 @@ import uuid
|
||||
import glob
|
||||
import traceback
|
||||
import platform
|
||||
import collections
|
||||
|
||||
PYTHON_VERSION = sys.version_info[0]
|
||||
if PYTHON_VERSION == 2:
|
||||
PYTHON_VERSION = sys.version_info[:3]
|
||||
if PYTHON_VERSION[0] == 2:
|
||||
import cPickle as pickle
|
||||
import cStringIO as StringIO
|
||||
import copy_reg as copyreg
|
||||
@@ -189,6 +188,12 @@ else:
|
||||
hashlib_md5 = lambda s: hashlib.md5(bytes(s,'utf8'))
|
||||
bytes, unicode = bytes, str
|
||||
|
||||
if PYTHON_VERSION[:2] < (2, 7):
|
||||
from gluon.contrib.ordereddict import OrderedDict
|
||||
else:
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
CALLABLETYPES = (types.LambdaType, types.FunctionType,
|
||||
types.BuiltinFunctionType,
|
||||
types.MethodType, types.BuiltinMethodType)
|
||||
@@ -855,7 +860,7 @@ class BaseAdapter(ConnectionPool):
|
||||
foreign_key = '%s (%s)' % (rtablename,
|
||||
rfieldname),
|
||||
table_name = tablename,
|
||||
field_name = field_name,
|
||||
field_name = field._rname or field.name,
|
||||
on_delete_action=field.ondelete)
|
||||
else:
|
||||
# make a guess here for circular references
|
||||
@@ -881,7 +886,7 @@ class BaseAdapter(ConnectionPool):
|
||||
)
|
||||
ftype = types[field_type[:9]] % dict(
|
||||
index_name = field_name+'__idx',
|
||||
field_name = field_name,
|
||||
field_name = field._rname or field.name,
|
||||
constraint_name = constraint_name,
|
||||
foreign_key = '%s (%s)' % (real_referenced,
|
||||
id_fieldname),
|
||||
@@ -958,13 +963,15 @@ class BaseAdapter(ConnectionPool):
|
||||
# geometry fields are added after the table has been created, not now
|
||||
if not (self.dbengine == 'postgres' and \
|
||||
field_type.startswith('geom')):
|
||||
fields.append('%s %s' % (field_name, ftype))
|
||||
#fetch the rname if it's there
|
||||
field_rname = "%s" % (field._rname or field_name)
|
||||
fields.append('%s %s' % (field_rname, ftype))
|
||||
other = ';'
|
||||
|
||||
# backend-specific extensions to fields
|
||||
if self.dbengine == 'mysql':
|
||||
if not hasattr(table, "_primarykey"):
|
||||
fields.append('PRIMARY KEY(%s)' % table._id.name)
|
||||
fields.append('PRIMARY KEY(%s)' % (table._id.name or table._id._rname))
|
||||
other = ' ENGINE=InnoDB CHARACTER SET utf8;'
|
||||
|
||||
fields = ',\n '.join(fields)
|
||||
@@ -979,7 +986,6 @@ class BaseAdapter(ConnectionPool):
|
||||
foreign_table = rtablename,
|
||||
foreign_key = ', '.join(pkeys),
|
||||
on_delete_action = field.ondelete)
|
||||
|
||||
#if there's a _rname, let's use that instead
|
||||
table_rname = table._rname or tablename
|
||||
|
||||
@@ -1252,7 +1258,7 @@ class BaseAdapter(ConnectionPool):
|
||||
def _insert(self, table, fields):
|
||||
table_rname = table._rname or table
|
||||
if fields:
|
||||
keys = ','.join(f.name for f, v in fields)
|
||||
keys = ','.join(f._rname or f.name for f, v in fields)
|
||||
values = ','.join(self.expand(v, f.type) for f, v in fields)
|
||||
return 'INSERT INTO %s(%s) VALUES (%s);' % (table_rname, keys, values)
|
||||
else:
|
||||
@@ -1437,7 +1443,10 @@ class BaseAdapter(ConnectionPool):
|
||||
table_rname = et._ot and et._tablename or et._rname or et._tablename
|
||||
else:
|
||||
table_rname = et._tablename
|
||||
out = '%s.%s' % (table_rname, expression.name)
|
||||
if not colnames:
|
||||
out = '%s.%s' % (table_rname, expression._rname or expression.name)
|
||||
else:
|
||||
out = '%s.%s' % (table_rname, expression.name)
|
||||
if field_type == 'string' and not expression.type in (
|
||||
'string','text','json','password'):
|
||||
out = self.CAST(out, self.types['text'])
|
||||
@@ -1513,7 +1522,7 @@ class BaseAdapter(ConnectionPool):
|
||||
sql_w = ' WHERE ' + self.expand(query)
|
||||
else:
|
||||
sql_w = ''
|
||||
sql_v = ','.join(['%s=%s' % (field.name,
|
||||
sql_v = ','.join(['%s=%s' % (field._rname or field.name,
|
||||
self.expand(value, field.type)) \
|
||||
for (field, value) in fields])
|
||||
tablename = "%s" % (self.db[tablename]._rname or tablename)
|
||||
@@ -1729,7 +1738,7 @@ class BaseAdapter(ConnectionPool):
|
||||
sql_o += ' ORDER BY %s' % ', '.join(
|
||||
['%s.%s'%(t,x) for t in tablenames for x in (
|
||||
hasattr(self.db[t],'_primarykey') and self.db[t]._primarykey
|
||||
or [self.db[t]._id.name]
|
||||
or [self.db[t]._id._rname or self.db[t]._id.name]
|
||||
)
|
||||
]
|
||||
)
|
||||
@@ -2302,7 +2311,7 @@ class SQLiteAdapter(BaseAdapter):
|
||||
else:
|
||||
self.dbpath = uri.split('://',1)[1]
|
||||
if self.dbpath[0] != '/':
|
||||
if PYTHON_VERSION == 2:
|
||||
if PYTHON_VERSION[0] == 2:
|
||||
self.dbpath = pjoin(
|
||||
self.folder.decode(path_encoding).encode('utf8'), self.dbpath)
|
||||
else:
|
||||
@@ -2312,7 +2321,7 @@ class SQLiteAdapter(BaseAdapter):
|
||||
if not 'detect_types' in driver_args and do_connect:
|
||||
driver_args['detect_types'] = self.driver.PARSE_DECLTYPES
|
||||
def connector(dbpath=self.dbpath, driver_args=driver_args):
|
||||
return self.driver.Connection(dbpath, **driver_args)
|
||||
return self.driver.Connection(dbpath, **driver_args)
|
||||
self.connector = connector
|
||||
if do_connect: self.reconnect()
|
||||
|
||||
@@ -2321,7 +2330,7 @@ class SQLiteAdapter(BaseAdapter):
|
||||
SQLiteAdapter.web2py_extract)
|
||||
self.connection.create_function("REGEXP", 2,
|
||||
SQLiteAdapter.web2py_regexp)
|
||||
|
||||
|
||||
if self.adapter_args.get('foreign_keys',True):
|
||||
self.execute('PRAGMA foreign_keys=ON;')
|
||||
|
||||
@@ -8141,7 +8150,7 @@ def index():
|
||||
if not db_group:
|
||||
del THREAD_LOCAL.db_instances[self._db_uid]
|
||||
|
||||
def executesql(self, query, placeholders=None, as_dict=False,
|
||||
def executesql(self, query, placeholders=None, as_dict=False,
|
||||
fields=None, colnames=None, as_ordered_dict=False):
|
||||
"""
|
||||
placeholders is optional and will always be None.
|
||||
@@ -8214,7 +8223,7 @@ def index():
|
||||
# convert the list for each row into a dictionary so it's
|
||||
# easier to work with. row['field_name'] rather than row[0]
|
||||
if as_ordered_dict:
|
||||
_dict = collections.OrderedDict
|
||||
_dict = OrderedDict
|
||||
else:
|
||||
_dict = dict
|
||||
return [_dict(zip(fields,row)) for row in data]
|
||||
@@ -8636,7 +8645,7 @@ class Table(object):
|
||||
referees = pr.pop(self._tablename)
|
||||
for referee in referees:
|
||||
self._referenced_by.append(referee)
|
||||
|
||||
|
||||
|
||||
def _filter_fields(self, record, id=False):
|
||||
return dict([(k, v) for (k, v) in record.iteritems() if k
|
||||
@@ -9576,6 +9585,7 @@ class Field(Expression):
|
||||
filter_out = None,
|
||||
custom_qualifier = None,
|
||||
map_none = None,
|
||||
rname = None
|
||||
):
|
||||
self._db = self.db = None # both for backward compatibility
|
||||
self.op = None
|
||||
@@ -9622,6 +9632,7 @@ class Field(Expression):
|
||||
self.label = label if label!=None else fieldname.replace('_',' ').title()
|
||||
self.requires = requires if requires!=None else []
|
||||
self.map_none = map_none
|
||||
self._rname = rname
|
||||
|
||||
def set_attributes(self,*args,**attributes):
|
||||
self.__dict__.update(*args,**attributes)
|
||||
@@ -9788,7 +9799,7 @@ class Field(Expression):
|
||||
return Expression(self.db, self.db._adapter.COUNT, self, distinct, 'integer')
|
||||
|
||||
def as_dict(self, flat=False, sanitize=True):
|
||||
attrs = ("name", 'authorize', 'represent', 'ondelete',
|
||||
attrs = ('name', 'authorize', 'represent', 'ondelete',
|
||||
'custom_store', 'autodelete', 'custom_retrieve',
|
||||
'filter_out', 'uploadseparate', 'widget', 'uploadfs',
|
||||
'update', 'custom_delete', 'uploadfield', 'uploadfolder',
|
||||
|
||||
Reference in New Issue
Block a user