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.
Files changed (149) hide show
  1. sqlobject/__init__.py +15 -0
  2. sqlobject/__version__.py +8 -0
  3. sqlobject/boundattributes.py +124 -0
  4. sqlobject/cache.py +376 -0
  5. sqlobject/classregistry.py +138 -0
  6. sqlobject/col.py +2187 -0
  7. sqlobject/compat.py +59 -0
  8. sqlobject/conftest.py +64 -0
  9. sqlobject/constraints.py +77 -0
  10. sqlobject/converters.py +278 -0
  11. sqlobject/dbconnection.py +1137 -0
  12. sqlobject/dberrors.py +54 -0
  13. sqlobject/declarative.py +211 -0
  14. sqlobject/events.py +365 -0
  15. sqlobject/firebird/__init__.py +8 -0
  16. sqlobject/firebird/firebirdconnection.py +463 -0
  17. sqlobject/include/__init__.py +1 -0
  18. sqlobject/include/hashcol.py +109 -0
  19. sqlobject/include/tests/__init__.py +1 -0
  20. sqlobject/include/tests/test_hashcol.py +84 -0
  21. sqlobject/index.py +189 -0
  22. sqlobject/inheritance/__init__.py +551 -0
  23. sqlobject/inheritance/iteration.py +106 -0
  24. sqlobject/inheritance/tests/__init__.py +1 -0
  25. sqlobject/inheritance/tests/test_aggregates.py +23 -0
  26. sqlobject/inheritance/tests/test_asdict.py +48 -0
  27. sqlobject/inheritance/tests/test_deep_inheritance.py +114 -0
  28. sqlobject/inheritance/tests/test_destroy_cascade.py +23 -0
  29. sqlobject/inheritance/tests/test_foreignKey.py +94 -0
  30. sqlobject/inheritance/tests/test_indexes.py +42 -0
  31. sqlobject/inheritance/tests/test_inheritance.py +164 -0
  32. sqlobject/inheritance/tests/test_inheritance_tree.py +50 -0
  33. sqlobject/joins.py +656 -0
  34. sqlobject/main.py +1880 -0
  35. sqlobject/manager/__init__.py +1 -0
  36. sqlobject/manager/command.py +1309 -0
  37. sqlobject/maxdb/__init__.py +8 -0
  38. sqlobject/maxdb/maxdbconnection.py +320 -0
  39. sqlobject/maxdb/readme.txt +27 -0
  40. sqlobject/mssql/__init__.py +8 -0
  41. sqlobject/mssql/mssqlconnection.py +417 -0
  42. sqlobject/mysql/__init__.py +8 -0
  43. sqlobject/mysql/mysqlconnection.py +562 -0
  44. sqlobject/postgres/__init__.py +8 -0
  45. sqlobject/postgres/pgconnection.py +619 -0
  46. sqlobject/sqlbuilder.py +1655 -0
  47. sqlobject/sqlite/__init__.py +8 -0
  48. sqlobject/sqlite/sqliteconnection.py +418 -0
  49. sqlobject/sresults.py +377 -0
  50. sqlobject/styles.py +174 -0
  51. sqlobject/sybase/__init__.py +8 -0
  52. sqlobject/sybase/sybaseconnection.py +183 -0
  53. sqlobject/tests/__init__.py +1 -0
  54. sqlobject/tests/dbtest.py +363 -0
  55. sqlobject/tests/test_ForeignKey.py +133 -0
  56. sqlobject/tests/test_ForeignKey_cascade.py +150 -0
  57. sqlobject/tests/test_NoneValuedResultItem.py +33 -0
  58. sqlobject/tests/test_SQLMultipleJoin.py +65 -0
  59. sqlobject/tests/test_SQLRelatedJoin.py +114 -0
  60. sqlobject/tests/test_SingleJoin.py +30 -0
  61. sqlobject/tests/test_aggregates.py +75 -0
  62. sqlobject/tests/test_aliases.py +49 -0
  63. sqlobject/tests/test_asdict.py +18 -0
  64. sqlobject/tests/test_auto.py +218 -0
  65. sqlobject/tests/test_basic.py +359 -0
  66. sqlobject/tests/test_blob.py +34 -0
  67. sqlobject/tests/test_boundattributes.py +67 -0
  68. sqlobject/tests/test_cache.py +57 -0
  69. sqlobject/tests/test_class_hash.py +22 -0
  70. sqlobject/tests/test_columns_order.py +18 -0
  71. sqlobject/tests/test_combining_joins.py +47 -0
  72. sqlobject/tests/test_comparison.py +24 -0
  73. sqlobject/tests/test_compat.py +10 -0
  74. sqlobject/tests/test_complex_sorting.py +77 -0
  75. sqlobject/tests/test_constraints.py +43 -0
  76. sqlobject/tests/test_converters.py +276 -0
  77. sqlobject/tests/test_create_drop.py +29 -0
  78. sqlobject/tests/test_csvexport.py +101 -0
  79. sqlobject/tests/test_csvimport.py +21 -0
  80. sqlobject/tests/test_cyclic_reference.py +55 -0
  81. sqlobject/tests/test_datetime.py +171 -0
  82. sqlobject/tests/test_dbconnection.py +17 -0
  83. sqlobject/tests/test_decimal.py +63 -0
  84. sqlobject/tests/test_declarative.py +83 -0
  85. sqlobject/tests/test_default_style.py +65 -0
  86. sqlobject/tests/test_delete.py +74 -0
  87. sqlobject/tests/test_distinct.py +36 -0
  88. sqlobject/tests/test_empty.py +22 -0
  89. sqlobject/tests/test_enum.py +75 -0
  90. sqlobject/tests/test_events.py +142 -0
  91. sqlobject/tests/test_exceptions.py +40 -0
  92. sqlobject/tests/test_expire.py +29 -0
  93. sqlobject/tests/test_groupBy.py +45 -0
  94. sqlobject/tests/test_identity.py +29 -0
  95. sqlobject/tests/test_indexes.py +100 -0
  96. sqlobject/tests/test_inheritance.py +35 -0
  97. sqlobject/tests/test_joins.py +160 -0
  98. sqlobject/tests/test_joins_conditional.py +143 -0
  99. sqlobject/tests/test_jsonbcol.py +53 -0
  100. sqlobject/tests/test_jsoncol.py +56 -0
  101. sqlobject/tests/test_lazy.py +165 -0
  102. sqlobject/tests/test_md5.py +13 -0
  103. sqlobject/tests/test_mysql.py +50 -0
  104. sqlobject/tests/test_new_joins.py +165 -0
  105. sqlobject/tests/test_parse_uri.py +147 -0
  106. sqlobject/tests/test_paste.py +92 -0
  107. sqlobject/tests/test_perConnection.py +20 -0
  108. sqlobject/tests/test_pickle.py +42 -0
  109. sqlobject/tests/test_picklecol.py +44 -0
  110. sqlobject/tests/test_postgres.py +82 -0
  111. sqlobject/tests/test_reparent_sqlmeta.py +33 -0
  112. sqlobject/tests/test_schema.py +30 -0
  113. sqlobject/tests/test_select.py +218 -0
  114. sqlobject/tests/test_select_through.py +63 -0
  115. sqlobject/tests/test_setters.py +23 -0
  116. sqlobject/tests/test_slice.py +59 -0
  117. sqlobject/tests/test_sorting.py +80 -0
  118. sqlobject/tests/test_sqlbuilder.py +134 -0
  119. sqlobject/tests/test_sqlbuilder_dbspecific.py +66 -0
  120. sqlobject/tests/test_sqlbuilder_importproxy.py +55 -0
  121. sqlobject/tests/test_sqlbuilder_joins_instances.py +90 -0
  122. sqlobject/tests/test_sqlite.py +160 -0
  123. sqlobject/tests/test_sqlmeta_idName.py +52 -0
  124. sqlobject/tests/test_sqlobject_admin.py +38 -0
  125. sqlobject/tests/test_string_id.py +79 -0
  126. sqlobject/tests/test_style.py +36 -0
  127. sqlobject/tests/test_subqueries.py +142 -0
  128. sqlobject/tests/test_transactions.py +122 -0
  129. sqlobject/tests/test_unicode.py +84 -0
  130. sqlobject/tests/test_uuidcol.py +40 -0
  131. sqlobject/tests/test_validation.py +125 -0
  132. sqlobject/tests/test_views.py +159 -0
  133. sqlobject/util/__init__.py +1 -0
  134. sqlobject/util/csvexport.py +210 -0
  135. sqlobject/util/csvimport.py +366 -0
  136. sqlobject/util/moduleloader.py +35 -0
  137. sqlobject/util/threadinglocal.py +6 -0
  138. sqlobject/versioning/__init__.py +120 -0
  139. sqlobject/versioning/test/__init__.py +0 -0
  140. sqlobject/versioning/test/test_version.py +183 -0
  141. sqlobject/views.py +151 -0
  142. sqlobject/wsgi_middleware.py +109 -0
  143. sqlobject-3.13.1.data/scripts/sqlobject-admin +36 -0
  144. sqlobject-3.13.1.data/scripts/sqlobject-convertOldURI +19 -0
  145. sqlobject-3.13.1.dist-info/METADATA +177 -0
  146. sqlobject-3.13.1.dist-info/RECORD +149 -0
  147. sqlobject-3.13.1.dist-info/WHEEL +6 -0
  148. sqlobject-3.13.1.dist-info/entry_points.txt +4 -0
  149. 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]