Hi Shai,
On 10/21/2014 04:04 PM, Shai Berger wrote:
> On Monday 20 October 2014 21:26:50 Carl Meyer wrote:
>> Hi Marc,
>>
>> On 10/19/2014 12:54 AM, Marc Tamlyn wrote:
>>> I guess now with migrations we have a nice way of running the SQL
>>> against the database to create the stored procedures.
>>>
>>> However if we plan to make this a public API, it should be a nice one.
>>> Something along the lines of db.procedures.proc_name(*args, **kwargs)
>>> would be preferable I think. Obviously this requires more magic to make
>>> it work (or explicit registration of your procedures).
>>
>> I know this is hypothetical, but I don't think that is a particularly
>> nicer API, or that we should provide such syntactic sugar atop
>> callproc(). Providing the procedure name as a string is not really a
>> problem, and is preferable to doing `__getattr__` magic or requiring
>> registration of procedures; the syntactic sugar just doesn't provide
>> enough benefit to justify the magic, and all the various ways that that
>> magic could confuse users and cause maintenance issues.
>>
> I respectfully disagree. The kind of "magic" Marc suggested lets you, as a
> user. treat procedure calls as function calls; that is a very natural thing to
> do.
Yes, I understand the attraction.
> I'd argue that in the common case, the user shouldn't care if the function
> they are calling is implemented in Python or Procedural SQL (assuming it is
> going to interact with the database either way), and so it is good API design
> to abstact this detail away.
Here is where we differ. I think calling a database stored procedure is
fundamentally a different thing from calling a Python function (even one
that accesses the database), and the difference should be obvious in the
calling code. I don't think it is good API design to abstract away
differences that the caller should be aware of. (For one example of a
difference, database stored procedures "return a modified copy of the
input arguments", which would be extremely unusual behavior for a normal
Python function.)
I think this is mostly a question of level. In an actual Django app that
uses stored procedures, I think it is quite likely a good idea for the
author of the app to provide a nice Python API that abstracts away the
internal implementation. But I think this API should be consciously
designed for-purpose (for example, it should likely return something
other than a possibly-modified copy of all its input arguments), and at
the level of Django core the benefits of a generic API that attempts to
mask the difference between Python functions and database stored
procedures are not enough to justify the magic required.
Perhaps I'm wrong - but I'd definitely want to see the utility of such a
generic "magic" layer proved as an external library before it gets added
to core.
Carl