You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<p>Or rather fork it and clone your fork. To develop a feature or a bugfix
63
+
create a separate branch, push it to your fork and create a pull request
64
+
to the original repo. That way CI will be triggered to test your code.</p>
61
65
<p>Voila! The packages are globally installed, but the files from the
62
-
checkout were not copied into <ttclass="docutils literal"><spanclass="pre">site-packages</span></tt>. See <ahref="http://pythonhosted.org/setuptools/" class="reference external">setuptools</a> for more.</p>
66
+
checkout were not copied into <ttclass="docutils literal"><spanclass="pre">site-packages</span></tt>. See <ahref="https://setuptools.readthedocs.io/en/latest/index.html" class="reference external">setuptools</a> for more.</p>
67
+
</div>
68
+
<divclass="section" id="architecture">
69
+
<h1>Architecture</h1>
70
+
<p>There are three main kinds of objects in SQLObject: tables, columns and
71
+
connections.</p>
72
+
<p>Tables-related objects are in <ahref="sqlobject/main.py.html" class="reference external">sqlobject/main.py</a> module. There are two
73
+
main classes: <ttclass="docutils literal">SQLObject</tt> and <ttclass="docutils literal">sqlmeta</tt>; the latter is not a
74
+
metaclass but a parent class for <ttclass="docutils literal">sqlmeta</tt> attribute in every class -
75
+
the authors tried to move there all attributes and methods not directly
76
+
related to columns to avoid cluttering table namespace.</p>
77
+
<p>Connections are instances of <ttclass="docutils literal">DBConnection</tt> class (from
78
+
<ahref="sqlobject/dbconnection.py.html" class="reference external">sqlobject/dbconnection.py</a>) and its concrete descendants.
79
+
<ttclass="docutils literal">DBConnection</tt> contains generic code for generating SQL, working with
80
+
transactions and so on. Concrete connection classes (like
81
+
<ttclass="docutils literal">PostgresConnection</tt> and <ttclass="docutils literal">SQLiteConnection</tt>) provide
<p>Columns are instances of classes from <ahref="sqlobject/col.py.html" class="reference external">sqlobject/col.py</a>. There are two
86
+
classes for every column: one is for user to include into an instance of
87
+
SQLObject, an instance of the other is automatically created by
88
+
SQLObject's metaclass. The two classes are usually named <ttclass="docutils literal">Col</tt> and
89
+
<ttclass="docutils literal">SOCol</tt>; for example, <ttclass="docutils literal">BoolCol</tt> and <ttclass="docutils literal">SOBoolCol</tt>. User-visible
90
+
classes, descendants of <ttclass="docutils literal">Col</tt>, seldom contain any code; the main code
91
+
for a column is in <ttclass="docutils literal">SOCol</tt> descendants and in validators.</p>
92
+
<p>Every column has a list of validators. Validators validate input data
93
+
and convert input data to python data and back. Every validator must
94
+
have methods <ttclass="docutils literal">from_python</tt> and <ttclass="docutils literal">to_python</tt>. The former converts data
95
+
from python to internal representation that will be converted by
96
+
converters to SQL strings. The latter converts data from SQL data to
97
+
python. Also please bear in mind that validators can receive <ttclass="docutils literal">None</tt>
98
+
(for SQL <ttclass="docutils literal">NULL</tt>) and <ttclass="docutils literal">SQLExpression</tt> (an object that represents
99
+
SQLObject expressions); both objects must be passed unchanged by
100
+
validators.</p>
101
+
<p>Converters from <ahref="sqlobject/converters.py.html" class="reference external">sqlobject/converters.py</a> aren't visible to users. They
102
+
are used behind the scene to convert objects returned by validators to
103
+
backend-specific SQL strings. The most elaborated converter is
104
+
<ttclass="docutils literal">StringLikeConverter</tt>. Yes, it converts strings to strings. It
105
+
converts python strings to SQL strings using backend-specific quoting
106
+
rules.</p>
107
+
<p>Let look into <ttclass="docutils literal">BoolCol</tt> as an example. The very <ttclass="docutils literal">BoolCol</tt> doesn't
108
+
have any code. <ttclass="docutils literal">SOBoolCol</tt> has a method to create <ttclass="docutils literal">BoolValidator</tt>
109
+
and methods to create backend-specific column type. <ttclass="docutils literal">BoolValidator</tt>
110
+
has identical methods <ttclass="docutils literal">from_python</tt> and <ttclass="docutils literal">to_python</tt>; the method
111
+
passes <ttclass="docutils literal">None</tt>, <ttclass="docutils literal">SQLExpression</tt> and bool values unchanged; int and
112
+
objects that have method <ttclass="docutils literal">__nonzero__</tt> are converted to bool; other
113
+
objects trigger validation error. Bool values that are returned by call
114
+
to <ttclass="docutils literal">from_python</tt> will be converted to SQL strings by
115
+
<ttclass="docutils literal">BoolConverter</tt>; bool values from <ttclass="docutils literal">to_python</tt> (is is supposed they
116
+
are originated from the backend via DB API driver) are passed to the
117
+
application.</p>
118
+
<p>Objects that are returned from <ttclass="docutils literal">from_python</tt> must be registered with
119
+
converters. Another approach for <ttclass="docutils literal">from_python</tt> is to return an object
120
+
that has <ttclass="docutils literal">__sqlrepr__</tt> method. Such objects convert to SQL strings
121
+
themselves, converters are not used.</p>
122
+
</div>
63
123
</div>
64
124
<divclass="section" id="style-guide">
65
125
<h1>Style Guide</h1>
66
-
<p>Generally you should follow the recommendations in <ahref="http://www.python.org/peps/pep-0008.html" class="reference external">PEP 8</a>, the
126
+
<p>Generally you should follow the recommendations in <ahref="http://www.python.org/dev/peps/pep-0008/" class="reference external">PEP 8</a>, the
67
127
Python Style Guide. Some things to take particular note of:</p>
68
128
<ulclass="simple">
69
129
<li>With a few exceptions sources must be <ahref="https://gitlab.com/pycqa/flake8" class="reference external">flake8</a>-clean (and hence
@@ -73,7 +133,7 @@ <h1>Style Guide</h1>
73
133
<ul>
74
134
<li><pclass="first"><strong>No tabs</strong>. Not anywhere. Always indent with 4 spaces.</p>
75
135
</li>
76
-
<li><pclass="first">I don't stress too much on line length. But try to break lines up
136
+
<li><pclass="first">We don't stress too much on line length. But try to break lines up
77
137
by grouping with parenthesis instead of with backslashes (if you
78
138
can). Do asserts like:</p>
79
139
<preclass="literal-block">
@@ -94,7 +154,7 @@ <h1>Style Guide</h1>
94
154
sqlobject import *</tt> so names should be fairly distinct, or they
95
155
shouldn't be exported in <ttclass="docutils literal">sqlobject.__init__</tt>.</p>
96
156
</li>
97
-
<li><pclass="first">I'm very picky about whitespace. There's one and only one right way
157
+
<li><pclass="first">We're very picky about whitespace. There's one and only one right way
98
158
to do it. Good examples:</p>
99
159
<preclass="literal-block">
100
160
short = 3
@@ -118,9 +178,9 @@ <h1>Style Guide</h1>
118
178
func( a, b )
119
179
[ 1, 2, 3 ]
120
180
</pre>
121
-
<p>To me, the poor use of whitespace seems lazy. I'll think less of
122
-
your code (justified or not) for this very trivial reason. I will
123
-
fix all your code for you if you don't do it yourself, because I
181
+
<p>To us, the poor use of whitespace seems lazy. We'll think less of
182
+
your code (justified or not) for this very trivial reason. We will
183
+
fix all your code for you if you don't do it yourself, because we
124
184
can't bear to look at sloppy whitespace.</p>
125
185
</li>
126
186
<li><pclass="first">Use <ttclass="docutils literal">@@</tt> to mark something that is suboptimal, or where you have a
@@ -174,9 +234,9 @@ <h1>Style Guide</h1>
174
234
<h1>Testing</h1>
175
235
<p>Tests are important. Tests keep everything from falling apart. All
176
236
new additions should have tests.</p>
177
-
<p>Testing uses py.test, an alternative to <ttclass="docutils literal">unittest</tt>. It is available at
<p>Testing uses py.test, an alternative to <ttclass="docutils literal">unittest</tt>. It is available
238
+
at <ahref="http://pytest.org/" class="reference external">http://pytest.org/</a> and <ahref="https://pypi.python.org/pypi/pytest" class="reference external">https://pypi.python.org/pypi/pytest</a>. Read its
239
+
<ahref="http://docs.pytest.org/en/latest/getting-started.html" class="reference external">getting started</a> document for more.</p>
180
240
<p>To actually run the test, you have to give it a database to connect to.
181
241
You do so with the option <ttclass="docutils literal"><spanclass="pre">-D</span></tt>. You can either give a complete URI or
182
242
one of several shortcuts like <ttclass="docutils literal">mysql</tt> (these shortcuts are defined in
@@ -192,22 +252,32 @@ <h1>Testing</h1>
192
252
<p><ttclass="docutils literal">supports(featureName)</tt> checks if the database backend supports the
193
253
named feature. What backends support what is defined at the top of
194
254
<ttclass="docutils literal">dbtest</tt>.</p>
195
-
<p>If you <ttclass="docutils literal">import *</tt> you'll also get py.test's version of <ahref="http://pytest.org/latest/assert.html#assertions-about-expected-exceptions" class="reference external">raises</a>, an
255
+
<p>If you <ttclass="docutils literal">import *</tt> you'll also get py.test's version of <ahref="http://docs.pytest.org/en/latest/assert.html#assertions-about-expected-exceptions" class="reference external">raises</a>, an
196
256
<ttclass="docutils literal">inserts</tt> function that can create instances for you, and a couple
197
257
miscellaneous functions.</p>
198
-
<p>If you submit a patch or implement a feature without a test, I'll be
199
-
forced to write the test. That's no fun for me, to just be writing
258
+
<p>If you submit a patch or implement a feature without a test, we'll be
259
+
forced to write the test. That's no fun for us, to just be writing
200
260
tests. So please, write tests; everything at least needs to be
201
261
exercised, even if the tests are absolutely complete.</p>
202
-
<p>We now use Travis CI to run tests. See the status:</p>
262
+
<p>We now use Travis CI and Circle CI to run tests. See the statuses:</p>
<p>To avoid triggering unnecessary test run at CI services add text <ahref="https://docs.travis-ci.com/user/customizing-the-build/#skipping-a-build" class="reference external">[skip ci]</a> or
266
+
<ahref="https://circleci.com/docs/skip-a-build/" class="reference external">[ci skip]</a> anywhere in your commit
267
+
messages for commits that don't change code (documentation updates and such).</p>
268
+
<p>We use <ahref="https://pypi.python.org/pypi/coverage" class="reference external">coverage.py</a>
269
+
to measures code coverage by tests and upload the result for analyzis to
270
+
<ahref="https://coveralls.io/github/sqlobject/sqlobject" class="reference external">Coveralls</a> and
<p>Imagine you have a list of persons, and every person plays a certain role.
47
58
Some persons are students, some are professors, some are employees. Every
48
59
role has different attributes. Students are known by their department and
@@ -197,10 +208,10 @@ <h2>Why</h2>
197
208
</pre>
198
209
</div>
199
210
<divclass="section" id="who-what-and-how">
200
-
<h2>Who, What and How</h2>
201
-
<p>Daniel Savard has implemented inheritance for SQLObject. According to
202
-
<ahref="http://www.objectmatter.com/vbsf/docs/maptool/ormapping.html" class="reference external">ObjectMatter</a> this is a kind of vertical inheritance. The only difference
203
-
is that objects reference their leaves, not parents. Links to parents are
211
+
<h2><ahref="#id3" class="toc-backref">Who, What and How</a></h2>
212
+
<p>Daniel Savard has implemented inheritance for SQLObject. In <ahref="https://cayenne.apache.org/docs/3.0/modeling-inheritance.html" class="reference external">terms of
213
+
ORM</a> this is a kind of vertical inheritance. The only difference is
214
+
that objects reference their leaves, not parents. Links to parents are
204
215
reconstructed at run-time using the hierarchy of Python classes.</p>
205
216
<ulclass="simple">
206
217
<li>As suggested by Ian Bicking, each child class now has the same
@@ -303,7 +314,7 @@ <h2>Who, What and How</h2>
303
314
</pre>
304
315
</div>
305
316
<divclass="section" id="limitations-and-notes">
306
-
<h2>Limitations and notes</h2>
317
+
<h2><ahref="#id4" class="toc-backref">Limitations and notes</a></h2>
307
318
<ulclass="simple">
308
319
<li>Only single inheritance will work. It is not possible to inherit
0 commit comments