sqlobject 3.13.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sqlobject/__init__.py +15 -0
- sqlobject/__version__.py +8 -0
- sqlobject/boundattributes.py +124 -0
- sqlobject/cache.py +376 -0
- sqlobject/classregistry.py +138 -0
- sqlobject/col.py +2187 -0
- sqlobject/compat.py +59 -0
- sqlobject/conftest.py +64 -0
- sqlobject/constraints.py +77 -0
- sqlobject/converters.py +278 -0
- sqlobject/dbconnection.py +1137 -0
- sqlobject/dberrors.py +54 -0
- sqlobject/declarative.py +211 -0
- sqlobject/events.py +365 -0
- sqlobject/firebird/__init__.py +8 -0
- sqlobject/firebird/firebirdconnection.py +463 -0
- sqlobject/include/__init__.py +1 -0
- sqlobject/include/hashcol.py +109 -0
- sqlobject/include/tests/__init__.py +1 -0
- sqlobject/include/tests/test_hashcol.py +84 -0
- sqlobject/index.py +189 -0
- sqlobject/inheritance/__init__.py +551 -0
- sqlobject/inheritance/iteration.py +106 -0
- sqlobject/inheritance/tests/__init__.py +1 -0
- sqlobject/inheritance/tests/test_aggregates.py +23 -0
- sqlobject/inheritance/tests/test_asdict.py +48 -0
- sqlobject/inheritance/tests/test_deep_inheritance.py +114 -0
- sqlobject/inheritance/tests/test_destroy_cascade.py +23 -0
- sqlobject/inheritance/tests/test_foreignKey.py +94 -0
- sqlobject/inheritance/tests/test_indexes.py +42 -0
- sqlobject/inheritance/tests/test_inheritance.py +164 -0
- sqlobject/inheritance/tests/test_inheritance_tree.py +50 -0
- sqlobject/joins.py +656 -0
- sqlobject/main.py +1880 -0
- sqlobject/manager/__init__.py +1 -0
- sqlobject/manager/command.py +1309 -0
- sqlobject/maxdb/__init__.py +8 -0
- sqlobject/maxdb/maxdbconnection.py +320 -0
- sqlobject/maxdb/readme.txt +27 -0
- sqlobject/mssql/__init__.py +8 -0
- sqlobject/mssql/mssqlconnection.py +417 -0
- sqlobject/mysql/__init__.py +8 -0
- sqlobject/mysql/mysqlconnection.py +562 -0
- sqlobject/postgres/__init__.py +8 -0
- sqlobject/postgres/pgconnection.py +619 -0
- sqlobject/sqlbuilder.py +1655 -0
- sqlobject/sqlite/__init__.py +8 -0
- sqlobject/sqlite/sqliteconnection.py +418 -0
- sqlobject/sresults.py +377 -0
- sqlobject/styles.py +174 -0
- sqlobject/sybase/__init__.py +8 -0
- sqlobject/sybase/sybaseconnection.py +183 -0
- sqlobject/tests/__init__.py +1 -0
- sqlobject/tests/dbtest.py +363 -0
- sqlobject/tests/test_ForeignKey.py +133 -0
- sqlobject/tests/test_ForeignKey_cascade.py +150 -0
- sqlobject/tests/test_NoneValuedResultItem.py +33 -0
- sqlobject/tests/test_SQLMultipleJoin.py +65 -0
- sqlobject/tests/test_SQLRelatedJoin.py +114 -0
- sqlobject/tests/test_SingleJoin.py +30 -0
- sqlobject/tests/test_aggregates.py +75 -0
- sqlobject/tests/test_aliases.py +49 -0
- sqlobject/tests/test_asdict.py +18 -0
- sqlobject/tests/test_auto.py +218 -0
- sqlobject/tests/test_basic.py +359 -0
- sqlobject/tests/test_blob.py +34 -0
- sqlobject/tests/test_boundattributes.py +67 -0
- sqlobject/tests/test_cache.py +57 -0
- sqlobject/tests/test_class_hash.py +22 -0
- sqlobject/tests/test_columns_order.py +18 -0
- sqlobject/tests/test_combining_joins.py +47 -0
- sqlobject/tests/test_comparison.py +24 -0
- sqlobject/tests/test_compat.py +10 -0
- sqlobject/tests/test_complex_sorting.py +77 -0
- sqlobject/tests/test_constraints.py +43 -0
- sqlobject/tests/test_converters.py +276 -0
- sqlobject/tests/test_create_drop.py +29 -0
- sqlobject/tests/test_csvexport.py +101 -0
- sqlobject/tests/test_csvimport.py +21 -0
- sqlobject/tests/test_cyclic_reference.py +55 -0
- sqlobject/tests/test_datetime.py +171 -0
- sqlobject/tests/test_dbconnection.py +17 -0
- sqlobject/tests/test_decimal.py +63 -0
- sqlobject/tests/test_declarative.py +83 -0
- sqlobject/tests/test_default_style.py +65 -0
- sqlobject/tests/test_delete.py +74 -0
- sqlobject/tests/test_distinct.py +36 -0
- sqlobject/tests/test_empty.py +22 -0
- sqlobject/tests/test_enum.py +75 -0
- sqlobject/tests/test_events.py +142 -0
- sqlobject/tests/test_exceptions.py +40 -0
- sqlobject/tests/test_expire.py +29 -0
- sqlobject/tests/test_groupBy.py +45 -0
- sqlobject/tests/test_identity.py +29 -0
- sqlobject/tests/test_indexes.py +100 -0
- sqlobject/tests/test_inheritance.py +35 -0
- sqlobject/tests/test_joins.py +160 -0
- sqlobject/tests/test_joins_conditional.py +143 -0
- sqlobject/tests/test_jsonbcol.py +53 -0
- sqlobject/tests/test_jsoncol.py +56 -0
- sqlobject/tests/test_lazy.py +165 -0
- sqlobject/tests/test_md5.py +13 -0
- sqlobject/tests/test_mysql.py +50 -0
- sqlobject/tests/test_new_joins.py +165 -0
- sqlobject/tests/test_parse_uri.py +147 -0
- sqlobject/tests/test_paste.py +92 -0
- sqlobject/tests/test_perConnection.py +20 -0
- sqlobject/tests/test_pickle.py +42 -0
- sqlobject/tests/test_picklecol.py +44 -0
- sqlobject/tests/test_postgres.py +82 -0
- sqlobject/tests/test_reparent_sqlmeta.py +33 -0
- sqlobject/tests/test_schema.py +30 -0
- sqlobject/tests/test_select.py +218 -0
- sqlobject/tests/test_select_through.py +63 -0
- sqlobject/tests/test_setters.py +23 -0
- sqlobject/tests/test_slice.py +59 -0
- sqlobject/tests/test_sorting.py +80 -0
- sqlobject/tests/test_sqlbuilder.py +134 -0
- sqlobject/tests/test_sqlbuilder_dbspecific.py +66 -0
- sqlobject/tests/test_sqlbuilder_importproxy.py +55 -0
- sqlobject/tests/test_sqlbuilder_joins_instances.py +90 -0
- sqlobject/tests/test_sqlite.py +160 -0
- sqlobject/tests/test_sqlmeta_idName.py +52 -0
- sqlobject/tests/test_sqlobject_admin.py +38 -0
- sqlobject/tests/test_string_id.py +79 -0
- sqlobject/tests/test_style.py +36 -0
- sqlobject/tests/test_subqueries.py +142 -0
- sqlobject/tests/test_transactions.py +122 -0
- sqlobject/tests/test_unicode.py +84 -0
- sqlobject/tests/test_uuidcol.py +40 -0
- sqlobject/tests/test_validation.py +125 -0
- sqlobject/tests/test_views.py +159 -0
- sqlobject/util/__init__.py +1 -0
- sqlobject/util/csvexport.py +210 -0
- sqlobject/util/csvimport.py +366 -0
- sqlobject/util/moduleloader.py +35 -0
- sqlobject/util/threadinglocal.py +6 -0
- sqlobject/versioning/__init__.py +120 -0
- sqlobject/versioning/test/__init__.py +0 -0
- sqlobject/versioning/test/test_version.py +183 -0
- sqlobject/views.py +151 -0
- sqlobject/wsgi_middleware.py +109 -0
- sqlobject-3.13.1.data/scripts/sqlobject-admin +36 -0
- sqlobject-3.13.1.data/scripts/sqlobject-convertOldURI +19 -0
- sqlobject-3.13.1.dist-info/METADATA +177 -0
- sqlobject-3.13.1.dist-info/RECORD +149 -0
- sqlobject-3.13.1.dist-info/WHEEL +6 -0
- sqlobject-3.13.1.dist-info/entry_points.txt +4 -0
- sqlobject-3.13.1.dist-info/top_level.txt +1 -0
sqlobject/index.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from itertools import count
|
|
2
|
+
from .converters import sqlrepr
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
creationOrder = count()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SODatabaseIndex(object):
|
|
9
|
+
|
|
10
|
+
def __init__(self,
|
|
11
|
+
soClass,
|
|
12
|
+
name,
|
|
13
|
+
columns,
|
|
14
|
+
creationOrder,
|
|
15
|
+
unique=False):
|
|
16
|
+
self.soClass = soClass
|
|
17
|
+
self.name = name
|
|
18
|
+
self.descriptions = self.convertColumns(columns)
|
|
19
|
+
self.creationOrder = creationOrder
|
|
20
|
+
self.unique = unique
|
|
21
|
+
|
|
22
|
+
def get(self, *args, **kw):
|
|
23
|
+
if not self.unique:
|
|
24
|
+
raise AttributeError(
|
|
25
|
+
"'%s' object has no attribute 'get' "
|
|
26
|
+
"(index is not unique)" % self.name)
|
|
27
|
+
connection = kw.pop('connection', None)
|
|
28
|
+
if args and kw:
|
|
29
|
+
raise TypeError("You cannot mix named and unnamed arguments")
|
|
30
|
+
columns = [d['column'] for d in self.descriptions if 'column' in d]
|
|
31
|
+
if kw and len(kw) != len(columns) or \
|
|
32
|
+
args and len(args) != len(columns):
|
|
33
|
+
raise TypeError(
|
|
34
|
+
"get() takes exactly %d argument and an optional "
|
|
35
|
+
"named argument 'connection' (%d given)" % (
|
|
36
|
+
len(columns), len(args) + len(kw)))
|
|
37
|
+
if args:
|
|
38
|
+
kw = {}
|
|
39
|
+
for i in range(len(args)):
|
|
40
|
+
if columns[i].foreignName is not None:
|
|
41
|
+
kw[columns[i].foreignName] = args[i]
|
|
42
|
+
else:
|
|
43
|
+
kw[columns[i].name] = args[i]
|
|
44
|
+
return self.soClass.selectBy(connection=connection, **kw).getOne()
|
|
45
|
+
|
|
46
|
+
def convertColumns(self, columns):
|
|
47
|
+
"""
|
|
48
|
+
Converts all the columns to dictionary descriptors;
|
|
49
|
+
dereferences string column names.
|
|
50
|
+
"""
|
|
51
|
+
new = []
|
|
52
|
+
for desc in columns:
|
|
53
|
+
if not isinstance(desc, dict):
|
|
54
|
+
desc = {'column': desc}
|
|
55
|
+
if 'expression' in desc:
|
|
56
|
+
assert 'column' not in desc, (
|
|
57
|
+
'You cannot provide both an expression and a column '
|
|
58
|
+
'(for %s in index %s in %s)' %
|
|
59
|
+
(desc, self.name, self.soClass))
|
|
60
|
+
assert 'length' not in desc, (
|
|
61
|
+
'length does not apply to expressions (for %s in '
|
|
62
|
+
'index %s in %s)' %
|
|
63
|
+
(desc, self.name, self.soClass))
|
|
64
|
+
new.append(desc)
|
|
65
|
+
continue
|
|
66
|
+
columnName = desc['column']
|
|
67
|
+
if not isinstance(columnName, str):
|
|
68
|
+
columnName = columnName.name
|
|
69
|
+
colDict = self.soClass.sqlmeta.columns
|
|
70
|
+
if columnName not in colDict:
|
|
71
|
+
for possible in colDict.values():
|
|
72
|
+
if possible.origName == columnName:
|
|
73
|
+
column = possible
|
|
74
|
+
break
|
|
75
|
+
else:
|
|
76
|
+
# None found
|
|
77
|
+
raise ValueError(
|
|
78
|
+
"The column by the name %r was not found "
|
|
79
|
+
"in the class %r" % (columnName, self.soClass))
|
|
80
|
+
else:
|
|
81
|
+
column = colDict[columnName]
|
|
82
|
+
desc['column'] = column
|
|
83
|
+
new.append(desc)
|
|
84
|
+
return new
|
|
85
|
+
|
|
86
|
+
def getExpression(self, desc, db):
|
|
87
|
+
if isinstance(desc['expression'], str):
|
|
88
|
+
return desc['expression']
|
|
89
|
+
else:
|
|
90
|
+
return sqlrepr(desc['expression'], db)
|
|
91
|
+
|
|
92
|
+
def sqliteCreateIndexSQL(self, soClass):
|
|
93
|
+
if self.unique:
|
|
94
|
+
uniqueOrIndex = 'UNIQUE INDEX'
|
|
95
|
+
else:
|
|
96
|
+
uniqueOrIndex = 'INDEX'
|
|
97
|
+
spec = []
|
|
98
|
+
for desc in self.descriptions:
|
|
99
|
+
if 'expression' in desc:
|
|
100
|
+
spec.append(self.getExpression(desc, 'sqlite'))
|
|
101
|
+
else:
|
|
102
|
+
spec.append(desc['column'].dbName)
|
|
103
|
+
ret = 'CREATE %s %s_%s ON %s (%s)' % \
|
|
104
|
+
(uniqueOrIndex,
|
|
105
|
+
self.soClass.sqlmeta.table,
|
|
106
|
+
self.name,
|
|
107
|
+
self.soClass.sqlmeta.table,
|
|
108
|
+
', '.join(spec))
|
|
109
|
+
return ret
|
|
110
|
+
|
|
111
|
+
postgresCreateIndexSQL = maxdbCreateIndexSQL = mssqlCreateIndexSQL = \
|
|
112
|
+
sybaseCreateIndexSQL = firebirdCreateIndexSQL = sqliteCreateIndexSQL
|
|
113
|
+
|
|
114
|
+
def mysqlCreateIndexSQL(self, soClass):
|
|
115
|
+
if self.unique:
|
|
116
|
+
uniqueOrIndex = 'UNIQUE'
|
|
117
|
+
else:
|
|
118
|
+
uniqueOrIndex = 'INDEX'
|
|
119
|
+
spec = []
|
|
120
|
+
for desc in self.descriptions:
|
|
121
|
+
if 'expression' in desc:
|
|
122
|
+
spec.append(self.getExpression(desc, 'mysql'))
|
|
123
|
+
elif 'length' in desc:
|
|
124
|
+
spec.append('%s(%d)' % (desc['column'].dbName, desc['length']))
|
|
125
|
+
else:
|
|
126
|
+
spec.append(desc['column'].dbName)
|
|
127
|
+
|
|
128
|
+
return 'ALTER TABLE %s ADD %s %s (%s)' % \
|
|
129
|
+
(soClass.sqlmeta.table, uniqueOrIndex,
|
|
130
|
+
self.name,
|
|
131
|
+
', '.join(spec))
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class DatabaseIndex(object):
|
|
135
|
+
"""
|
|
136
|
+
This takes a variable number of parameters, each of which is a
|
|
137
|
+
column for indexing. Each column may be a column object or the
|
|
138
|
+
string name of the column (*not* the database name). You may also
|
|
139
|
+
use dictionaries, to further customize the indexing of the column.
|
|
140
|
+
The dictionary may have certain keys:
|
|
141
|
+
|
|
142
|
+
'column':
|
|
143
|
+
The column object or string identifier.
|
|
144
|
+
'length':
|
|
145
|
+
MySQL will only index the first N characters if this is
|
|
146
|
+
given. For other databases this is ignored.
|
|
147
|
+
'expression':
|
|
148
|
+
You can create an index based on an expression, e.g.,
|
|
149
|
+
'lower(column)'. This can either be a string or a sqlbuilder
|
|
150
|
+
expression.
|
|
151
|
+
|
|
152
|
+
Further keys may be added to the column specs in the future.
|
|
153
|
+
|
|
154
|
+
The class also take the keyword argument `unique`; if true then
|
|
155
|
+
a UNIQUE index is created.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
baseClass = SODatabaseIndex
|
|
159
|
+
|
|
160
|
+
def __init__(self, *columns, **kw):
|
|
161
|
+
kw['columns'] = columns
|
|
162
|
+
self.kw = kw
|
|
163
|
+
self.creationOrder = next(creationOrder)
|
|
164
|
+
|
|
165
|
+
def setName(self, value):
|
|
166
|
+
assert self.kw.get('name') is None, \
|
|
167
|
+
"You cannot change a name after it has already been set " \
|
|
168
|
+
"(from %s to %s)" % (self.kw['name'], value)
|
|
169
|
+
self.kw['name'] = value
|
|
170
|
+
|
|
171
|
+
def _get_name(self):
|
|
172
|
+
return self.kw['name']
|
|
173
|
+
|
|
174
|
+
def _set_name(self, value):
|
|
175
|
+
self.setName(value)
|
|
176
|
+
|
|
177
|
+
name = property(_get_name, _set_name)
|
|
178
|
+
|
|
179
|
+
def withClass(self, soClass):
|
|
180
|
+
return self.baseClass(soClass=soClass,
|
|
181
|
+
creationOrder=self.creationOrder, **self.kw)
|
|
182
|
+
|
|
183
|
+
def __repr__(self):
|
|
184
|
+
return '<%s %s %s>' % (
|
|
185
|
+
self.__class__.__name__,
|
|
186
|
+
hex(abs(id(self)))[2:],
|
|
187
|
+
self.kw)
|
|
188
|
+
|
|
189
|
+
__all__ = ['DatabaseIndex']
|