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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from sqlobject import StringCol
|
|
2
|
+
from sqlobject.inheritance import InheritableSQLObject
|
|
3
|
+
from sqlobject.tests.dbtest import setupClass
|
|
4
|
+
|
|
5
|
+
########################################
|
|
6
|
+
# sqlmeta.asDict
|
|
7
|
+
########################################
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class InheritablePersonAD(InheritableSQLObject):
|
|
11
|
+
firstName = StringCol()
|
|
12
|
+
lastName = StringCol(alternateID=True, length=100)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ManagerAD(InheritablePersonAD):
|
|
16
|
+
department = StringCol()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class EmployeeAD(InheritablePersonAD):
|
|
20
|
+
_inheritable = False
|
|
21
|
+
so_position = StringCol()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_getColumns():
|
|
25
|
+
setupClass([InheritablePersonAD, ManagerAD, EmployeeAD])
|
|
26
|
+
|
|
27
|
+
for klass, columns in (
|
|
28
|
+
(InheritablePersonAD, ['firstName', 'lastName']),
|
|
29
|
+
(ManagerAD, ['department', 'firstName', 'lastName']),
|
|
30
|
+
(EmployeeAD, ['firstName', 'lastName', 'so_position'])):
|
|
31
|
+
_columns = sorted(klass.sqlmeta.getColumns().keys())
|
|
32
|
+
assert _columns == columns
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_asDict():
|
|
36
|
+
setupClass([InheritablePersonAD, ManagerAD, EmployeeAD], force=True)
|
|
37
|
+
InheritablePersonAD(firstName='Oneof', lastName='Authors')
|
|
38
|
+
ManagerAD(firstName='ManagerAD', lastName='The', department='Dep')
|
|
39
|
+
EmployeeAD(firstName='Project', lastName='Leader',
|
|
40
|
+
so_position='Project leader')
|
|
41
|
+
|
|
42
|
+
assert InheritablePersonAD.get(1).sqlmeta.asDict() == \
|
|
43
|
+
dict(firstName='Oneof', lastName='Authors', id=1)
|
|
44
|
+
assert InheritablePersonAD.get(2).sqlmeta.asDict() == \
|
|
45
|
+
dict(firstName='ManagerAD', lastName='The', department='Dep', id=2)
|
|
46
|
+
assert InheritablePersonAD.get(3).sqlmeta.asDict() == \
|
|
47
|
+
dict(firstName='Project', lastName='Leader',
|
|
48
|
+
so_position='Project leader', id=3)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
from pytest import raises, skip
|
|
2
|
+
from sqlobject import ForeignKey, MultipleJoin, StringCol
|
|
3
|
+
from sqlobject.inheritance import InheritableSQLObject
|
|
4
|
+
from sqlobject.tests.dbtest import getConnection, setupClass, supports
|
|
5
|
+
|
|
6
|
+
########################################
|
|
7
|
+
# Deep Inheritance
|
|
8
|
+
########################################
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DIPerson(InheritableSQLObject):
|
|
12
|
+
firstName = StringCol(length=100)
|
|
13
|
+
lastName = StringCol(alternateID=True, length=100)
|
|
14
|
+
manager = ForeignKey("DIManager", default=None)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DIEmployee(DIPerson):
|
|
18
|
+
so_position = StringCol(unique=True, length=100)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DIManager(DIEmployee):
|
|
22
|
+
subdudes = MultipleJoin("DIPerson", joinColumn="manager_id")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_creation_fail():
|
|
26
|
+
"""
|
|
27
|
+
Try to create a Manager without specifying a position.
|
|
28
|
+
This should fail without leaving any partial records in
|
|
29
|
+
the database.
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
setupClass([DIManager, DIEmployee, DIPerson])
|
|
33
|
+
|
|
34
|
+
kwargs = {'firstName': 'John', 'lastname': 'Doe'}
|
|
35
|
+
raises(TypeError, DIManager, **kwargs)
|
|
36
|
+
persons = DIEmployee.select(DIPerson.q.firstName == 'John')
|
|
37
|
+
assert persons.count() == 0
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_creation_fail2():
|
|
41
|
+
"""
|
|
42
|
+
Try to create two Managers with the same position.
|
|
43
|
+
This should fail without leaving any partial records in
|
|
44
|
+
the database.
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
setupClass([DIManager, DIEmployee, DIPerson])
|
|
48
|
+
|
|
49
|
+
kwargs = {'firstName': 'John', 'lastName': 'Doe',
|
|
50
|
+
'so_position': 'Project Manager'}
|
|
51
|
+
DIManager(**kwargs)
|
|
52
|
+
persons = DIEmployee.select(DIPerson.q.firstName == 'John')
|
|
53
|
+
assert persons.count() == 1
|
|
54
|
+
|
|
55
|
+
kwargs = {'firstName': 'John', 'lastName': 'Doe II',
|
|
56
|
+
'so_position': 'Project Manager'}
|
|
57
|
+
raises(Exception, DIManager, **kwargs)
|
|
58
|
+
persons = DIPerson.select(DIPerson.q.firstName == 'John')
|
|
59
|
+
assert persons.count() == 1
|
|
60
|
+
|
|
61
|
+
if not supports('transactions'):
|
|
62
|
+
skip("Transactions aren't supported")
|
|
63
|
+
transaction = DIPerson._connection.transaction()
|
|
64
|
+
kwargs = {'firstName': 'John', 'lastName': 'Doe III',
|
|
65
|
+
'so_position': 'Project Manager'}
|
|
66
|
+
raises(Exception, DIManager, connection=transaction, **kwargs)
|
|
67
|
+
transaction.rollback()
|
|
68
|
+
transaction.begin()
|
|
69
|
+
persons = DIPerson.select(DIPerson.q.firstName == 'John',
|
|
70
|
+
connection=transaction)
|
|
71
|
+
assert persons.count() == 1
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_deep_inheritance():
|
|
75
|
+
conn = getConnection()
|
|
76
|
+
if conn.module.__name__ == 'mysql.connector' \
|
|
77
|
+
and conn.connector_type == 'mysql.connector-python':
|
|
78
|
+
skip("connector-python falls into an infinite loop here")
|
|
79
|
+
|
|
80
|
+
setupClass([DIManager, DIEmployee, DIPerson])
|
|
81
|
+
|
|
82
|
+
manager = DIManager(firstName='Project', lastName='Manager',
|
|
83
|
+
so_position='Project Manager')
|
|
84
|
+
manager_id = manager.id
|
|
85
|
+
employee_id = DIEmployee(firstName='Project', lastName='Leader',
|
|
86
|
+
so_position='Project leader', manager=manager).id
|
|
87
|
+
DIPerson(firstName='Oneof', lastName='Authors', manager=manager)
|
|
88
|
+
|
|
89
|
+
cache = conn.cache
|
|
90
|
+
cache.clear()
|
|
91
|
+
|
|
92
|
+
managers = list(DIManager.select())
|
|
93
|
+
assert len(managers) == 1
|
|
94
|
+
cache.clear()
|
|
95
|
+
|
|
96
|
+
employees = list(DIEmployee.select())
|
|
97
|
+
assert len(employees) == 2
|
|
98
|
+
cache.clear()
|
|
99
|
+
|
|
100
|
+
persons = list(DIPerson.select())
|
|
101
|
+
assert len(persons) == 3
|
|
102
|
+
cache.clear()
|
|
103
|
+
|
|
104
|
+
person = DIPerson.get(employee_id)
|
|
105
|
+
assert isinstance(person, DIEmployee)
|
|
106
|
+
|
|
107
|
+
person = DIPerson.get(manager_id)
|
|
108
|
+
assert isinstance(person, DIEmployee)
|
|
109
|
+
assert isinstance(person, DIManager)
|
|
110
|
+
cache.clear()
|
|
111
|
+
|
|
112
|
+
person = DIEmployee.get(manager_id)
|
|
113
|
+
assert isinstance(person, DIManager)
|
|
114
|
+
conn.close()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from sqlobject import ForeignKey, IntCol, SQLObject
|
|
2
|
+
from sqlobject.inheritance import InheritableSQLObject
|
|
3
|
+
from sqlobject.tests.dbtest import setupClass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SOTestCascade1(InheritableSQLObject):
|
|
7
|
+
dummy = IntCol()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SOTestCascade2(SOTestCascade1):
|
|
11
|
+
c = ForeignKey('SOTestCascade3', cascade='null')
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SOTestCascade3(SQLObject):
|
|
15
|
+
dummy = IntCol()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_destroySelf():
|
|
19
|
+
setupClass([SOTestCascade1, SOTestCascade3, SOTestCascade2])
|
|
20
|
+
|
|
21
|
+
c = SOTestCascade3(dummy=1)
|
|
22
|
+
SOTestCascade2(cID=c.id, dummy=1)
|
|
23
|
+
c.destroySelf()
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from sqlobject import ForeignKey, SQLObject, StringCol
|
|
2
|
+
from sqlobject.tests.dbtest import setupClass
|
|
3
|
+
from sqlobject.inheritance import InheritableSQLObject
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Note(SQLObject):
|
|
7
|
+
text = StringCol()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PersonWithNotes(InheritableSQLObject):
|
|
11
|
+
firstName = StringCol()
|
|
12
|
+
lastName = StringCol()
|
|
13
|
+
note = ForeignKey("Note", default=None)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Paper(SQLObject):
|
|
17
|
+
content = StringCol()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class EmployeeWithNotes(PersonWithNotes):
|
|
21
|
+
_inheritable = False
|
|
22
|
+
paper = ForeignKey("Paper", default=None)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_foreignKey():
|
|
26
|
+
setupClass([Note, PersonWithNotes, Paper, EmployeeWithNotes], force=True)
|
|
27
|
+
|
|
28
|
+
note = Note(text="person")
|
|
29
|
+
PersonWithNotes(firstName='Oneof', lastName='Authors', note=note)
|
|
30
|
+
note = Note(text="employee")
|
|
31
|
+
EmployeeWithNotes(firstName='Project', lastName='Leader', note=note)
|
|
32
|
+
|
|
33
|
+
paper = Paper(content="secret")
|
|
34
|
+
EmployeeWithNotes(firstName='Senior', lastName='Clerk', paper=paper)
|
|
35
|
+
PersonWithNotes(firstName='Some', lastName='Person')
|
|
36
|
+
|
|
37
|
+
person = PersonWithNotes.get(1)
|
|
38
|
+
assert isinstance(person, PersonWithNotes) and \
|
|
39
|
+
not isinstance(person, EmployeeWithNotes)
|
|
40
|
+
assert person.note.text == "person"
|
|
41
|
+
|
|
42
|
+
employee = EmployeeWithNotes.get(2)
|
|
43
|
+
assert isinstance(employee, EmployeeWithNotes)
|
|
44
|
+
assert employee.note.text == "employee"
|
|
45
|
+
save_employee = employee
|
|
46
|
+
|
|
47
|
+
# comparison to None needed to build the right SQL expression
|
|
48
|
+
persons = PersonWithNotes.select(PersonWithNotes.q.noteID != None) # noqa
|
|
49
|
+
assert persons.count() == 2
|
|
50
|
+
|
|
51
|
+
persons = PersonWithNotes.selectBy(noteID=person.note.id)
|
|
52
|
+
assert persons.count() == 1
|
|
53
|
+
|
|
54
|
+
# comparison to None needed to build the right SQL expression
|
|
55
|
+
employee = EmployeeWithNotes.select(
|
|
56
|
+
PersonWithNotes.q.noteID != None) # noqa
|
|
57
|
+
assert employee.count() == 1
|
|
58
|
+
|
|
59
|
+
persons = PersonWithNotes.selectBy(noteID=person.note.id)
|
|
60
|
+
assert persons.count() == 1
|
|
61
|
+
|
|
62
|
+
persons = PersonWithNotes.selectBy(note=person.note)
|
|
63
|
+
assert persons.count() == 1
|
|
64
|
+
|
|
65
|
+
persons = PersonWithNotes.selectBy(note=None)
|
|
66
|
+
assert persons.count() == 2
|
|
67
|
+
|
|
68
|
+
employee = EmployeeWithNotes.selectBy(paperID=None)
|
|
69
|
+
assert employee.count() == 1
|
|
70
|
+
|
|
71
|
+
employee = EmployeeWithNotes.selectBy(paper=None)
|
|
72
|
+
assert employee.count() == 1
|
|
73
|
+
|
|
74
|
+
employee = EmployeeWithNotes.selectBy(note=save_employee.note,
|
|
75
|
+
paper=save_employee.paper)
|
|
76
|
+
assert employee.count() == 1
|
|
77
|
+
|
|
78
|
+
employee = EmployeeWithNotes.selectBy()
|
|
79
|
+
assert employee.count() == 2
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class SOTestInhBase(InheritableSQLObject):
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class SOTestInhFKey(SOTestInhBase):
|
|
87
|
+
base = ForeignKey("SOTestInhBase")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_foreignKey2():
|
|
91
|
+
setupClass([SOTestInhBase, SOTestInhFKey])
|
|
92
|
+
|
|
93
|
+
test = SOTestInhBase()
|
|
94
|
+
SOTestInhFKey(base=test)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from sqlobject import DatabaseIndex, IntCol, StringCol
|
|
2
|
+
from sqlobject.tests.dbtest import setupClass
|
|
3
|
+
from sqlobject.inheritance import InheritableSQLObject
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class InhPersonIdxGet(InheritableSQLObject):
|
|
7
|
+
first_name = StringCol(notNone=True, length=100)
|
|
8
|
+
last_name = StringCol(notNone=True, length=100)
|
|
9
|
+
age = IntCol()
|
|
10
|
+
pk = DatabaseIndex(first_name, last_name, unique=True)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class InhEmployeeIdxGet(InhPersonIdxGet):
|
|
14
|
+
security_number = IntCol()
|
|
15
|
+
experience = IntCol()
|
|
16
|
+
sec_index = DatabaseIndex(security_number, unique=True)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class InhSalesManIdxGet(InhEmployeeIdxGet):
|
|
20
|
+
_inheritable = False
|
|
21
|
+
skill = IntCol()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_index_get_1():
|
|
25
|
+
setupClass([InhPersonIdxGet, InhEmployeeIdxGet, InhSalesManIdxGet])
|
|
26
|
+
|
|
27
|
+
InhSalesManIdxGet(first_name='Michael', last_name='Pallin', age=65,
|
|
28
|
+
security_number=2304, experience=2, skill=10)
|
|
29
|
+
InhEmployeeIdxGet(first_name='Eric', last_name='Idle', age=63,
|
|
30
|
+
security_number=3402, experience=9)
|
|
31
|
+
InhPersonIdxGet(first_name='Terry', last_name='Guilliam', age=64)
|
|
32
|
+
|
|
33
|
+
InhPersonIdxGet.pk.get('Michael', 'Pallin')
|
|
34
|
+
InhEmployeeIdxGet.pk.get('Michael', 'Pallin')
|
|
35
|
+
InhSalesManIdxGet.pk.get('Michael', 'Pallin')
|
|
36
|
+
InhPersonIdxGet.pk.get('Eric', 'Idle')
|
|
37
|
+
InhEmployeeIdxGet.pk.get('Eric', 'Idle')
|
|
38
|
+
InhPersonIdxGet.pk.get(first_name='Terry', last_name='Guilliam')
|
|
39
|
+
InhEmployeeIdxGet.sec_index.get(2304)
|
|
40
|
+
InhEmployeeIdxGet.sec_index.get(3402)
|
|
41
|
+
InhSalesManIdxGet.sec_index.get(2304)
|
|
42
|
+
InhSalesManIdxGet.sec_index.get(3402)
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pytest import raises
|
|
3
|
+
from sqlobject import IntCol, StringCol
|
|
4
|
+
from sqlobject.inheritance import InheritableSQLObject
|
|
5
|
+
from sqlobject.tests.dbtest import getConnection, setupClass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
connection = getConnection()
|
|
10
|
+
except (AttributeError, NameError):
|
|
11
|
+
# The module was imported during documentation building
|
|
12
|
+
pass
|
|
13
|
+
else:
|
|
14
|
+
if connection.module.__name__ == 'mysql.connector' \
|
|
15
|
+
and connection.connector_type == 'mysql.connector-python':
|
|
16
|
+
pytestmark = pytest.mark.skip(
|
|
17
|
+
"connector-python falls into an infinite loop here")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
########################################
|
|
21
|
+
# Inheritance
|
|
22
|
+
########################################
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class InheritablePerson(InheritableSQLObject):
|
|
26
|
+
firstName = StringCol(length=100)
|
|
27
|
+
lastName = StringCol(alternateID=True, length=100)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Employee(InheritablePerson):
|
|
31
|
+
_inheritable = False
|
|
32
|
+
so_position = StringCol(length=100)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def setup():
|
|
36
|
+
setupClass(InheritablePerson)
|
|
37
|
+
setupClass(Employee)
|
|
38
|
+
|
|
39
|
+
Employee(firstName='Project', lastName='Leader',
|
|
40
|
+
so_position='Project leader')
|
|
41
|
+
InheritablePerson(firstName='Oneof', lastName='Authors')
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_creation_fail():
|
|
45
|
+
setup()
|
|
46
|
+
kwargs = {'firstName': 'John', 'lastname': 'Doe'}
|
|
47
|
+
raises(TypeError, Employee, **kwargs)
|
|
48
|
+
persons = InheritablePerson.select(InheritablePerson.q.firstName == 'John')
|
|
49
|
+
assert persons.count() == 0
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_inheritance():
|
|
53
|
+
setup()
|
|
54
|
+
|
|
55
|
+
persons = InheritablePerson.select() # all
|
|
56
|
+
for person in persons:
|
|
57
|
+
assert isinstance(person, InheritablePerson)
|
|
58
|
+
if isinstance(person, Employee):
|
|
59
|
+
assert not hasattr(person, "childName")
|
|
60
|
+
else:
|
|
61
|
+
assert hasattr(person, "childName")
|
|
62
|
+
assert not person.childName
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_inheritance_select():
|
|
66
|
+
setup()
|
|
67
|
+
|
|
68
|
+
# comparison to None needed to build the right SQL expression
|
|
69
|
+
persons = InheritablePerson.select(
|
|
70
|
+
InheritablePerson.q.firstName != None) # noqa
|
|
71
|
+
assert persons.count() == 2
|
|
72
|
+
|
|
73
|
+
persons = InheritablePerson.select(InheritablePerson.q.firstName == "phd")
|
|
74
|
+
assert persons.count() == 0
|
|
75
|
+
|
|
76
|
+
# comparison to None needed to build the right SQL expression
|
|
77
|
+
employees = Employee.select(Employee.q.firstName != None) # noqa
|
|
78
|
+
assert employees.count() == 1
|
|
79
|
+
|
|
80
|
+
employees = Employee.select(Employee.q.firstName == "phd")
|
|
81
|
+
assert employees.count() == 0
|
|
82
|
+
|
|
83
|
+
# comparison to None needed to build the right SQL expression
|
|
84
|
+
employees = Employee.select(Employee.q.so_position != None) # noqa
|
|
85
|
+
assert employees.count() == 1
|
|
86
|
+
|
|
87
|
+
persons = InheritablePerson.selectBy(firstName="Project")
|
|
88
|
+
assert persons.count() == 1
|
|
89
|
+
assert isinstance(persons[0], Employee)
|
|
90
|
+
|
|
91
|
+
persons = Employee.selectBy(firstName="Project")
|
|
92
|
+
assert persons.count() == 1
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
person = InheritablePerson.byLastName("Oneof")
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
98
|
+
else:
|
|
99
|
+
raise RuntimeError("unknown person %s" % person)
|
|
100
|
+
|
|
101
|
+
person = InheritablePerson.byLastName("Leader")
|
|
102
|
+
assert person.firstName == "Project"
|
|
103
|
+
|
|
104
|
+
person = Employee.byLastName("Leader")
|
|
105
|
+
assert person.firstName == "Project"
|
|
106
|
+
|
|
107
|
+
persons = list(InheritablePerson.select(
|
|
108
|
+
orderBy=InheritablePerson.q.lastName))
|
|
109
|
+
assert len(persons) == 2
|
|
110
|
+
|
|
111
|
+
persons = list(InheritablePerson.select(orderBy=(
|
|
112
|
+
InheritablePerson.q.lastName, InheritablePerson.q.firstName)))
|
|
113
|
+
assert len(persons) == 2
|
|
114
|
+
|
|
115
|
+
persons = list(Employee.select(orderBy=Employee.q.lastName))
|
|
116
|
+
assert len(persons) == 1
|
|
117
|
+
|
|
118
|
+
persons = list(Employee.select(orderBy=(Employee.q.lastName,
|
|
119
|
+
Employee.q.firstName)))
|
|
120
|
+
assert len(persons) == 1
|
|
121
|
+
|
|
122
|
+
persons = list(Employee.select(orderBy=Employee.q.so_position))
|
|
123
|
+
assert len(persons) == 1
|
|
124
|
+
|
|
125
|
+
persons = list(Employee.select(orderBy=(Employee.q.so_position,
|
|
126
|
+
Employee.q.lastName)))
|
|
127
|
+
assert len(persons) == 1
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_addDelColumn():
|
|
131
|
+
setup()
|
|
132
|
+
|
|
133
|
+
assert hasattr(InheritablePerson, "firstName")
|
|
134
|
+
assert hasattr(Employee, "firstName")
|
|
135
|
+
assert hasattr(InheritablePerson.q, "firstName")
|
|
136
|
+
assert hasattr(Employee.q, "firstName")
|
|
137
|
+
|
|
138
|
+
Employee.sqlmeta.addColumn(IntCol('runtime', default=None))
|
|
139
|
+
|
|
140
|
+
assert not hasattr(InheritablePerson, 'runtime')
|
|
141
|
+
assert hasattr(Employee, 'runtime')
|
|
142
|
+
assert not hasattr(InheritablePerson.q, 'runtime')
|
|
143
|
+
assert hasattr(Employee.q, 'runtime')
|
|
144
|
+
|
|
145
|
+
InheritablePerson.sqlmeta.addColumn(IntCol('runtime2', default=None))
|
|
146
|
+
|
|
147
|
+
assert hasattr(InheritablePerson, 'runtime2')
|
|
148
|
+
assert hasattr(Employee, 'runtime2')
|
|
149
|
+
assert hasattr(InheritablePerson.q, 'runtime2')
|
|
150
|
+
assert hasattr(Employee.q, 'runtime2')
|
|
151
|
+
|
|
152
|
+
Employee.sqlmeta.delColumn('runtime')
|
|
153
|
+
|
|
154
|
+
assert not hasattr(InheritablePerson, 'runtime')
|
|
155
|
+
assert not hasattr(Employee, 'runtime')
|
|
156
|
+
assert not hasattr(InheritablePerson.q, 'runtime')
|
|
157
|
+
assert not hasattr(Employee.q, 'runtime')
|
|
158
|
+
|
|
159
|
+
InheritablePerson.sqlmeta.delColumn('runtime2')
|
|
160
|
+
|
|
161
|
+
assert not hasattr(InheritablePerson, 'runtime2')
|
|
162
|
+
assert not hasattr(Employee, 'runtime2')
|
|
163
|
+
assert not hasattr(InheritablePerson.q, 'runtime2')
|
|
164
|
+
assert not hasattr(Employee.q, 'runtime2')
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from pytest import skip
|
|
2
|
+
from sqlobject import StringCol
|
|
3
|
+
from sqlobject.inheritance import InheritableSQLObject
|
|
4
|
+
from sqlobject.tests.dbtest import getConnection, setupClass
|
|
5
|
+
|
|
6
|
+
########################################
|
|
7
|
+
# Inheritance Tree
|
|
8
|
+
########################################
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Tree1(InheritableSQLObject):
|
|
12
|
+
aprop = StringCol(length=10)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Tree2(Tree1):
|
|
16
|
+
bprop = StringCol(length=10)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Tree3(Tree1):
|
|
20
|
+
cprop = StringCol(length=10)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Tree4(Tree2):
|
|
24
|
+
dprop = StringCol(length=10)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Tree5(Tree2):
|
|
28
|
+
eprop = StringCol(length=10)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_tree():
|
|
32
|
+
conn = getConnection()
|
|
33
|
+
if conn.module.__name__ == 'mysql.connector' \
|
|
34
|
+
and conn.connector_type == 'mysql.connector-python':
|
|
35
|
+
skip("connector-python falls into an infinite loop here")
|
|
36
|
+
|
|
37
|
+
setupClass([Tree1, Tree2, Tree3, Tree4, Tree5])
|
|
38
|
+
|
|
39
|
+
Tree1(aprop='t1') # t1
|
|
40
|
+
t2 = Tree2(aprop='t2', bprop='t2')
|
|
41
|
+
Tree3(aprop='t3', cprop='t3') # t3
|
|
42
|
+
t4 = Tree4(aprop='t4', bprop='t4', dprop='t4')
|
|
43
|
+
t5 = Tree5(aprop='t5', bprop='t5', eprop='t5')
|
|
44
|
+
|
|
45
|
+
# find just the t5 out of childs from Tree2
|
|
46
|
+
assert t5 == Tree1.select(Tree2.q.childName == 'Tree5')[0]
|
|
47
|
+
|
|
48
|
+
# t2,t4,t5 are all subclasses of Tree1 with t1 childName of 'Tree2'
|
|
49
|
+
assert list(Tree1.select(
|
|
50
|
+
Tree1.q.childName == 'Tree2', orderBy="aprop")) == [t2, t4, t5]
|