SQL string prefix idea
The idea is to add a new string prefix 's' for SQL string. This string doesn't do anything in Python, unlike b"" or f"" strings, but interactive Python shells like IPython or Jupyter can parse the following characters as SQL syntax instead of Python syntax and give SQL syntax highlighting and autocompletion, and if they are configured correctly, they can do column name autocompletion. Unfortunately when I try to type s"select * from table" it gave me syntax error instead, so I think this need to be implemented in Python language itself instead of module
Like PEP-501 https://www.python.org/dev/peps/pep-0501/ ? Le ven. 21 févr. 2020 à 15:28, Jonathan Fine <jfine2358@gmail.com> a écrit :
Hi I like the problem, but not the solution suggested. -- Jonathan _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ZQLROD... Code of Conduct: http://python.org/psf/codeofconduct/
-- Antoine Rozo
May I suggest mark string with comments instead of populating the interpreter with lost of "string" templates? Something like "SELECT * FROM table" # string: sql Or "<p><strong>spam</strong> ham eggs</p> # template: html IDEs can read this comment and highlight (and do some other static checks) on the commented strings. It can be easily combined with raw strings and f-strings such as: f"<p><strong>{my_string}</strong> ham</p>" # doctype: html
This idea by jdveiga seems like a good one. It doesn't require any change in Python, although conceivably an informational PEP could make some specific convention a recommendation. The thing is, SQL isn't THAT special. I use SQL a lot myself, so would benefit from such support. But there are LOTS of mini-languages that I might work with as strings in Python. Pandas queries; Numexpr transformations; XPath queries; HTML; Regex; MongoDB queries; JSON query (which I think is mostly the same as MongoDB); LDAP query; GraphQL; and lots of others. I certainly don't want to make new string types for every one of these. And I don't even want special syntax to allow an arbitrary string style. In concept, something like an f-string declaration might be possible: query = f"{SELECT * FROM table|@sql}" I'm not sure if that off-the-cuff "suggestion" would be possible in Python's parser, but just to show the vague idea. But a comment convention feels much lighter here. On Fri, Feb 21, 2020 at 10:16 AM <jdveiga@gmail.com> wrote:
May I suggest mark string with comments instead of populating the interpreter with lost of "string" templates?
Something like "SELECT * FROM table" # string: sql
Or "<p><strong>spam</strong> ham eggs</p> # template: html
IDEs can read this comment and highlight (and do some other static checks) on the commented strings.
It can be easily combined with raw strings and f-strings such as:
f"<p><strong>{my_string}</strong> ham</p>" # doctype: html _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/7FWPN7... Code of Conduct: http://python.org/psf/codeofconduct/
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
On Feb 21, 2020, at 05:54, minecraft2048@gmail.com wrote:
lUnfortunately when I try to type s"select * from table" it gave me syntax error instead, so I think this need to be implemented in Python language itself instead of module
Well, it can be implemented with a module if your module installs an import hook. Unfortunately, the boilerplate to write an import hook is more complicated than you’d like (and pretty hard to figure out the first time), and the support for filtering on the token stream (the most obvious way to do this one) rather than the text stream, AST, or bytecode is pretty minimal and clumsy. It may be worth trying to teach yourself anyway, because you learn a lot about Python along the way, but I don’t know that the result is something you’d actually want to use (See https://github.com/abarnert/floatliteralhack for hints; I think that’s the shortest—although definitely not cleanest—way to install a token-filtering import hook for Python 3.4, and only a few things have changed since then.)
On Fri, Feb 21, 2020 at 04:26:01AM -0000, minecraft2048@gmail.com wrote:
The idea is to add a new string prefix 's' for SQL string. This string doesn't do anything in Python
That ought to rule it out then. Why are we adding syntax to the language that doesn't get used anywhere in the language? All that means is one more thing to confuse the reader: Q: What's the difference between s'Hello world' and 'Hello world'? A: Nothing. one more thing for beginners to learn, one more feature for the interpreter to support, and for no benefit to the language. It's not like adding a new operator or syntactic form like the @ operator or extended slicing, both of which were added for the sake of numpy. Once added to the language, *anyone* could use them in their own code. Whereas this s-string would add no new functionality for people to use, prevent the language ever using an s-prefix for something useful, and give benefit only to users of particular enhanced interactive environments. And what's so special about SQL over, say, regular expressions, XML, JSON, YAML, Markdown, ReST, LaTeX, etc? I might want to use the s'' prefix for embedded Scheme code rather than SQL.
interactive Python shells like IPython or Jupyter can parse the following characters as SQL syntax instead of Python syntax and give SQL syntax highlighting and autocompletion
They can do that right now, if they desire. SQL syntax is distinctive enough that if IPython wants to highlight SQL syntax, without any changes to the language or the string, it could do so. Besides, IPython already adds magic to their command line. If they wanted to add more magic in the form of s-strings, we can't stop them. -- Steven
On Sat, Feb 22, 2020 at 11:58:58AM +1100, Steven D'Aprano wrote:
And what's so special about SQL over, say, regular expressions, XML, JSON, YAML, Markdown, ReST, LaTeX, etc? I might want to use the s'' prefix for embedded Scheme code rather than SQL.
*cough* Um, regular expressions are not precisely the best example there, since we do have raw strings specifically for regular expressions. But the rest of the list is still valid. Why is SQL more important than any other language or text format? I don't think it is. -- Steven
On Fri, Feb 21, 2020 at 9:26 PM Steven D'Aprano <steve@pearwood.info> wrote:
And what's so special about SQL over, say, regular expressions, XML, JSON, YAML, Markdown, ReST, LaTeX, etc? I might want to use the s'' prefix for embedded Scheme code rather than SQL.
Um, regular expressions are not precisely the best example there, since we do have raw strings specifically for regular expressions.
I mentioned them also in my similar list, but deliberately. *Raw strings* are not per-se for regexen, even if that is one of the more common uses. That said, I wonder why no text editors I know of try special highlighting of `r"..."` strings. We already (often) have that hint that the quoted thing might be a regular expression. Maybe it's just that those patterns are so densely coded that adding colors doesn't really help. Doing a search, the only editor I find easily that seems to highlight regexen is JetBrains Rider. The examples it shows look kinda-sorta useful. Probably someone made a plugin or something that does it elsewhere. Here's another idea that is purely convention, as the comment convention is. Use functions! They are just cruft from a runtime point-of-view, but they provide a really obvious hint to IDEs or other tools: SQL = REGX = XPATH = MD = lambda s: s pat = REGX(r"\$\d{1,10}.\d{2}") sql = SQL("SELECT foo, bar FROM table WHERE baz > 42;") query = XPATH("/bookstore/book[1]/title") These decorations are doing nothing functionally, but they would be easy for any IDE that wanted to to look for. This is completely extensible to any mini-language that might occur in strings. You'd just need some sort of configuration for the editor to know how to look for and highlight each syntax. I kinda like the look of this better than the end of line comment (which gets more complex to figure out with multi-line, triple-quoted strings. The function just handles that automatically. Of course, those functions *could* do something more than identity if they wanted to.
But the rest of the list is still valid. Why is SQL more important than any other language or text format? I don't think it is.
I might even go so far as saying SQL is more important than any other SINGLE other embedded language. But out of the hundreds, it's nowhere close to a majority. -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
On Fri, Feb 21, 2020 at 10:19:37PM -0500, David Mertz wrote:
On Fri, Feb 21, 2020 at 9:26 PM Steven D'Aprano <steve@pearwood.info> wrote:
And what's so special about SQL over, say, regular expressions, XML, JSON, YAML, Markdown, ReST, LaTeX, etc? I might want to use the s'' prefix for embedded Scheme code rather than SQL.
Um, regular expressions are not precisely the best example there, since we do have raw strings specifically for regular expressions.
I mentioned them also in my similar list, but deliberately. *Raw strings* are not per-se for regexen, even if that is one of the more common uses.
Actually, in Python, regexes are the primary reason raw strings were added! Raw strings aren't quite fully raw, which is why you can't use raw strings for Windows paths: path = r'somewhere\some\folder\' doesn't work. The reason is that "raw" (semi-cooked?) strings are intended for regexes, not as a general mechanism for disabling string escape codes, and regexes aren't allow to end with a bare backslash. https://docs.python.org/3/faq/design.html#why-can-t-raw-strings-r-strings-en... -- Steven
Hello, Just a quick correction, in case a begginer sees this thread. You can use raw strings for Windows paths, except when they end with a backslash. This works: path = r'somewhere\some\folder' filepath = r'somewhere\some\folder\file.txt' This also works: from os import sep path = r'somewhere\some\folder' + sep This doesn't work: path = r'somewhere\some\folder\' Best regards, João Matos On 22/02/2020 06:26, Steven D'Aprano wrote:
On Fri, Feb 21, 2020 at 10:19:37PM -0500, David Mertz wrote:
On Fri, Feb 21, 2020 at 9:26 PM Steven D'Aprano <steve@pearwood.info> wrote:
And what's so special about SQL over, say, regular expressions, XML, JSON, YAML, Markdown, ReST, LaTeX, etc? I might want to use the s'' prefix for embedded Scheme code rather than SQL. Um, regular expressions are not precisely the best example there, since we do have raw strings specifically for regular expressions.
I mentioned them also in my similar list, but deliberately. *Raw strings* are not per-se for regexen, even if that is one of the more common uses. Actually, in Python, regexes are the primary reason raw strings were added!
Raw strings aren't quite fully raw, which is why you can't use raw strings for Windows paths:
path = r'somewhere\some\folder\'
doesn't work. The reason is that "raw" (semi-cooked?) strings are intended for regexes, not as a general mechanism for disabling string escape codes, and regexes aren't allow to end with a bare backslash.
https://docs.python.org/3/faq/design.html#why-can-t-raw-strings-r-strings-en...
On 22/02/2020 06:26, Steven D'Aprano wrote:
Actually, in Python, regexes are the primary reason raw strings were added!
Raw strings aren't quite fully raw, which is why you can't use raw strings for Windows paths:
path = r'somewhere\some\folder\'
doesn't work. The reason is that "raw" (semi-cooked?) strings are
s/are/were/
intended for regexes, not as a general mechanism for disabling string escape codes, and regexes aren't allow to end with a bare backslash.
https://docs.python.org/3/faq/design.html#why-can-t-raw-strings-r-strings-en...
So maybe it's time to make raw strings really raw? They do have uses other than regexes, as your path example shows. I've been bitten by this gotcha a few times. Your docs link states "... they allow you to pass on the string quote character by escaping it with a backslash." I don't have access to a Python 3 version right now, but that is not true in Python 2: Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "licence" for more information.
r'x\'y'
"x\\'y"
list(_)
['x', '\\', "'", 'y'] (Apologies for the double vertical spacing, I'm wrestling with my email server.) Rob Cliffe
On Mon, Mar 16, 2020 at 9:08 AM Rob Cliffe via Python-ideas <python-ideas@python.org> wrote:
On 22/02/2020 06:26, Steven D'Aprano wrote:
Actually, in Python, regexes are the primary reason raw strings were added!
Raw strings aren't quite fully raw, which is why you can't use raw strings for Windows paths:
path = r'somewhere\some\folder\'
doesn't work. The reason is that "raw" (semi-cooked?) strings are
s/are/were/
intended for regexes, not as a general mechanism for disabling string escape codes, and regexes aren't allow to end with a bare backslash.
https://docs.python.org/3/faq/design.html#why-can-t-raw-strings-r-strings-en...
So maybe it's time to make raw strings really raw? They do have uses other than regexes, as your path example shows.
I've been bitten by this gotcha a few times.
Your docs link states "... they allow you to pass on the string quote character by escaping it with a backslash."
Currently, string prefixes don't determine when the string ends. Neither raw strings nor f-strings can end the string anywhere other than the place a vanilla string literal would:
f"asdf{'qwer"zxcv'}1234" File "<stdin>", line 1 f"asdf{'qwer"zxcv'}1234" ^ SyntaxError: invalid syntax f"""asdf{'qwer"zxcv'}1234""" 'asdfqwer"zxcv1234'
I don't know how deeply baked into the language this requirement is, but it's certainly something that makes things easier for all forms of syntax highlighting etc. ChrisA
Rob Cliffe wrote:
Your docs link states "... they allow you to pass on the string quote character by escaping it with a backslash."
I don't have access to a Python 3 version right now, but that is not true in Python 2: [snip]
The behavior is the same on Python 3.8.2: Python 3.8.2 (default, Feb 26 2020, 22:21:03) [GCC 9.2.1 20200130] on linux Type "help", "copyright", "credits" or "license" for more information.
r'x\'y' "x\\'y" list(_) ['x', '\\', "'", 'y']
What is unclear to me (regarding the quoted line from the Design FAQ) is that backslashes can be used in normal strings to properly escape the same quote type without the above issue:
'x\'y' "x'y" list(_) ['x', "'", 'y']
Perhaps the "they" is intended to mean something other than "raw strings". Based on the context, I think "they" might be instead referring to the previously mentioned text processors (such as regex engines). As in "In return, [those processors] allow you to pass on the string quote character by escaping it with a backslash". Or perhaps the above behavior wasn't always the case. Either way, I think that part of the Design FAQ could benefit from an update to make that more clear, I can see how the current wording could be a bit ambiguous. Unless I'm mistaken about the intended meaning, the above fix could make for a decent "newcomer friendly"/easy issue. I can open an issue on bugs.python.org for someone else to work on as a first PR; it would be a very straightforward (but still helpful) trivial fix. On Sun, Mar 15, 2020 at 6:09 PM Rob Cliffe via Python-ideas < python-ideas@python.org> wrote:
On 22/02/2020 06:26, Steven D'Aprano wrote:
Actually, in Python, regexes are the primary reason raw strings were added!
Raw strings aren't quite fully raw, which is why you can't use raw strings for Windows paths:
path = r'somewhere\some\folder\'
doesn't work. The reason is that "raw" (semi-cooked?) strings are
s/are/were/
intended for regexes, not as a general mechanism for disabling string escape codes, and regexes aren't allow to end with a bare backslash.
https://docs.python.org/3/faq/design.html#why-can-t-raw-strings-r-strings-en...
So maybe it's time to make raw strings really raw? They do have uses other than regexes, as your path example shows.
I've been bitten by this gotcha a few times.
Your docs link states "... they allow you to pass on the string quote character by escaping it with a backslash."
I don't have access to a Python 3 version right now, but that is not true in Python 2:
Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "licence" for more information.
r'x\'y'
"x\\'y"
list(_)
['x', '\\', "'", 'y']
(Apologies for the double vertical spacing, I'm wrestling with my email server.)
Rob Cliffe _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/IABDEO... Code of Conduct: http://python.org/psf/codeofconduct/
Kyle Stanley writes:
The behavior is the same on Python 3.8.2:
Python 3.8.2 (default, Feb 26 2020, 22:21:03) [GCC 9.2.1 20200130] on linux Type "help", "copyright", "credits" or "license" for more information.
r'x\'y' "x\\'y"
This looks like a defect to me. The "'" *is* being quoted. I.e., there is no syntax error, like this: >>> 'x'y' File "<stdin>", line 1 'x'y' ^ SyntaxError: invalid syntax but the quoting character "\" is not being removed.
On 22/02/2020 06:26, Steven D'Aprano wrote:
Raw strings aren't quite fully raw, which is why you can't use raw strings for Windows paths:
path = r'somewhere\some\folder\'
doesn't work. The reason is that "raw" (semi-cooked?) strings are s/are/were/ intended for regexes[.]
With all due respect to Steve d'A, I think that reason is inaccurate (at least in MacPorts' Python 3.8.2). I get >>> path = r'somewhere\some\folder\' File "<stdin>", line 1 path = r'somewhere\some\folder\' ^ SyntaxError: EOL while scanning string literal The reason for that, I believe, is that the rightmost "'" is quoted, and there is no "'" terminating the string literal. Note: I'm just spitballing based on behavior, I haven't looked at the code (sorry, I don't know that code and don't have time to study it). Steve
On Mon, Mar 16, 2020 at 02:36:25PM +0900, Stephen J. Turnbull wrote:
Kyle Stanley writes:
The behavior is the same on Python 3.8.2:
Python 3.8.2 (default, Feb 26 2020, 22:21:03) [GCC 9.2.1 20200130] on linux Type "help", "copyright", "credits" or "license" for more information.
r'x\'y' "x\\'y"
This looks like a defect to me. The "'" *is* being quoted.
If it's a defect, it's one which goes all the way back to Python 1.5: [steve@ando ~]$ python1.5 >>> r'x\'y' "x\\'y" and is fully documented :-) [quote] Even in a raw literal, quotes can be escaped with a backslash, but the backslash remains in the result; for example, r"\"" is a valid string literal consisting of two characters: a backslash and a double quote; r"\" is not a valid string literal (even a raw string cannot end in an odd number of backslashes). [/quote] https://docs.python.org/3/reference/lexical_analysis.html#literals
Raw strings aren't quite fully raw, which is why you can't use raw strings for Windows paths: path = r'somewhere\some\folder\' doesn't work. The reason is that "raw" (semi-cooked?) strings are s/are/were/ intended for regexes[.]
With all due respect to Steve d'A, I think that reason is inaccurate (at least in MacPorts' Python 3.8.2). I get
>>> path = r'somewhere\some\folder\' File "<stdin>", line 1 path = r'somewhere\some\folder\' ^ SyntaxError: EOL while scanning string literal
The reason for that, I believe, is that the rightmost "'" is quoted, and there is no "'" terminating the string literal.
Yes, that's what I meant when I said "it doesn't work". And the reason it doesn't work, as I understand it, is that raw strings were designed for use in regular expressions. Regexes cannot end in an odd number of backslashes. -- Steven
On Feb 21, 2020, at 19:22, David Mertz <mertz@gnosis.cx> wrote:
Of course, those functions *could* do something more than identity if they wanted to.
And the nice thing is that if you only later need to make it do something, there’s no refactoring needed—just `SQL=lru_cache(conn.compile)` or whatever and you’re done.
PyCharm (I think only the paid edition) does recognise SQL in plain string literals just because it looks like SQL, and it offers various features from there including syntax highlighting. It also recognises that the first argument to functions like `re.match` is a regex and has features for that, regardless of whether you use raw strings.
On Sat, Feb 22, 2020 at 12:54 AM <minecraft2048@gmail.com> wrote:
The idea is to add a new string prefix 's' for SQL string. This string doesn't do anything in Python, unlike b"" or f"" strings, but interactive Python shells like IPython or Jupyter can parse the following characters as SQL syntax instead of Python syntax and give SQL syntax highlighting and autocompletion, and if they are configured correctly, they can do column name autocompletion. Unfortunately when I try to type s"select * from table" it gave me syntax error instead, so I think this need to be implemented in Python language itself instead of module
All other forms of string prefix have syntactic significance, but you're asking for something that has semantic significance instead. I suggest that this would be better served by a completely different feature: type recognition. An SQL query can be considered to be a specific data type (even though it's effectively a string), and type inference can recognize that a string that'll eventually be passed to a "run query" function must be a query. In the cases where inference isn't sufficient, add a type hint. Either way, the editor can use that info to syntax-highlight the string appropriately. ChrisA
On Fri, Feb 21, 2020 at 5:53 AM <minecraft2048@gmail.com> wrote:
The idea is to add a new string prefix 's' for SQL string. This string doesn't do anything in Python, unlike b"" or f"" strings, but interactive Python shells like IPython or Jupyter can parse the following characters as SQL syntax instead of Python syntax and give SQL syntax highlighting and autocompletion, and if they are configured correctly, they can do column name autocompletion. Unfortunately when I try to type s"select * from table" it gave me syntax error instead, so I think this need to be implemented in Python language itself instead of module
First, as to SQL specifically, writing literal SQL in code is a bad idea. It's easy to have bugs, especially sql injection. You should use an ORM at the very least a SQL builder. Instead of: sf"select * from sometable where name = '{userName}'" you would write something like: sql.query(SomeTable).filter_by(name=userName).all() And I believe the same thing applies to HTML and just about anything else that has a complicated enough syntax that this idea would be useful for. Second, if I had a strong reason to do something like this, I'd want to use a function that enabled me to add run-time sanity checking (at least during development and testing phase): _html_(f"This is a <b><i>{adverb} bad</b></i> example.") and in production that function would just return the value untouched. --- Bruce
On Sat, Feb 22, 2020 at 2:38 PM Bruce Leban <bruce@leban.us> wrote:
First, as to SQL specifically, writing literal SQL in code is a bad idea. It's easy to have bugs, especially sql injection. You should use an ORM at the very least a SQL builder. Instead of:
sf"select * from sometable where name = '{userName}'"
you would write something like:
sql.query(SomeTable).filter_by(name=userName).all()
I disagree with the blanket statement here. Writing literal SQL in code is fine - but you have to treat it *as* code. It is code. It is not something you blindly interpolate strings into. If it's just a constant string, with no interpolation whatsoever, then you're fine. If you're building it out of pieces that you maintain entire control over (for instance, having a list of column names, which you then join with commas and slap in there), then that's also fine. It's only when you put uncontrolled data into an SQL query that you have a problem. In your example: con.execute("select * from sometable where name = ?", (username,)) would be a perfectly safe way to work with a table using literal SQL queries, since there is no interpolation of user data.
And I believe the same thing applies to HTML and just about anything else that has a complicated enough syntax that this idea would be useful for.
Second, if I had a strong reason to do something like this, I'd want to use a function that enabled me to add run-time sanity checking (at least during development and testing phase):
_html_(f"This is a <b><i>{adverb} bad</b></i> example.")
and in production that function would just return the value untouched.
If you're going to do the validation, do it in production as well. That's where you're more likely to get attackers. But even better is, again, parameterization. ChrisA
OMG, please no! Please, for all that is decent, do not use an ORM in any code I will ever need to look at! The SQL injection attack is just silly if you don't run arbitrary strings. Don't ever do that. But running a query that is hard coded as text, with just a few parameters filled in (the DB-API is handy) is good... yes, check those parameters for sanity and permission first. On Fri, Feb 21, 2020 at 10:39 PM Bruce Leban <bruce@leban.us> wrote:
On Fri, Feb 21, 2020 at 5:53 AM <minecraft2048@gmail.com> wrote:
The idea is to add a new string prefix 's' for SQL string. This string doesn't do anything in Python, unlike b"" or f"" strings, but interactive Python shells like IPython or Jupyter can parse the following characters as SQL syntax instead of Python syntax and give SQL syntax highlighting and autocompletion, and if they are configured correctly, they can do column name autocompletion. Unfortunately when I try to type s"select * from table" it gave me syntax error instead, so I think this need to be implemented in Python language itself instead of module
First, as to SQL specifically, writing literal SQL in code is a bad idea. It's easy to have bugs, especially sql injection. You should use an ORM at the very least a SQL builder. Instead of:
sf"select * from sometable where name = '{userName}'"
you would write something like:
sql.query(SomeTable).filter_by(name=userName).all()
And I believe the same thing applies to HTML and just about anything else that has a complicated enough syntax that this idea would be useful for.
Second, if I had a strong reason to do something like this, I'd want to use a function that enabled me to add run-time sanity checking (at least during development and testing phase):
_html_(f"This is a <b><i>{adverb} bad</b></i> example.")
and in production that function would just return the value untouched.
--- Bruce _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/GVTWOF... Code of Conduct: http://python.org/psf/codeofconduct/
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
There are many variants of SQL. DB-API only solves for so much. From "[Python-ideas] Draft PEP on string interpolation" (=> f-strings) https://groups.google.com/d/msg/python-ideas/6tfm3e2UtDU/8ugqbZtYAwAJ : ```quote IIUC, to do this with SQL,
sql(i'select {date:as_date} from {tablename}'
needs to be ['select ', unescaped(date, 'as_date'), 'from ', unescaped(tablename)] so that e.g. sql_92(), sql_2011() would know that 'select ' is presumably implicitly escaped * https://en.wikipedia.org/wiki/SQL#Interoperability_and_standardization * http://docs.sqlalchemy.org/en/rel_1_0/dialects/ * https://docs.djangoproject.com/en/1.7/ref/models/queries/#f-expressions "Django F-Expressions" ``` And from the next message: ```quote [... Django F-Objects, Q-Objects, deferred evaluation due to schema dialects] Each ORM (and DBAPI) [has] parametrization settings (e.g. '%' or '?' or configuration_setting) which should not collide with the f-string syntax. * DBAPI v2.0 https://www.python.org/dev/peps/pep-0249/ * SQLite DBAPI https://docs.python.org/2/library/sqlite3.html https://docs.python.org/3/library/sqlite3.html http://docs.sqlalchemy.org/en/rel_1_0/core/tutorial.html#conjunctions
s = select([(users.c.fullname + ... ", " + addresses.c.email_address). ... label('title')]).\ ... where(users.c.id == addresses.c.user_id).\ ... where(users.c.name.between('m', 'z')).\ ... where( ... or_( ... addresses.c.email_address.like('%@aol.com'), ... addresses.c.email_address.like('%@msn.com') ... ) ... ) conn.execute(s).fetchall() SELECT users.fullname || ? || addresses.email_address AS title FROM users, addresses WHERE users.id = addresses.user_id AND users.name BETWEEN ? AND ? AND (addresses.email_address LIKE ? OR addresses.email_address LIKE ?) (', ', 'm', 'z', '%@aol.com', '%@msn.com') [(u'Wendy Williams, wendy@aol.com',)]
from sqlalchemy.sql import text s = text( ... "SELECT users.fullname || ', ' || addresses.email_address AS title " ... "FROM users, addresses " ... "WHERE users.id = addresses.user_id " ... "AND users.name BETWEEN :x AND :y " ... "AND (addresses.email_address LIKE :e1 " ... "OR addresses.email_address LIKE :e2)") SQL conn.execute(s, x='m', y='z', e1='%@aol.com', e2='%@msn.com').fetchall()
[(u'Wendy Williams, wendy@aol.com',)] ``` On Sat, Feb 22, 2020 at 12:35 AM David Mertz <mertz@gnosis.cx> wrote:
OMG, please no! Please, for all that is decent, do not use an ORM in any code I will ever need to look at!
The SQL injection attack is just silly if you don't run arbitrary strings. Don't ever do that. But running a query that is hard coded as text, with just a few parameters filled in (the DB-API is handy) is good... yes, check those parameters for sanity and permission first.
On Fri, Feb 21, 2020 at 10:39 PM Bruce Leban <bruce@leban.us> wrote:
On Fri, Feb 21, 2020 at 5:53 AM <minecraft2048@gmail.com> wrote:
The idea is to add a new string prefix 's' for SQL string. This string doesn't do anything in Python, unlike b"" or f"" strings, but interactive Python shells like IPython or Jupyter can parse the following characters as SQL syntax instead of Python syntax and give SQL syntax highlighting and autocompletion, and if they are configured correctly, they can do column name autocompletion. Unfortunately when I try to type s"select * from table" it gave me syntax error instead, so I think this need to be implemented in Python language itself instead of module
First, as to SQL specifically, writing literal SQL in code is a bad idea. It's easy to have bugs, especially sql injection. You should use an ORM at the very least a SQL builder. Instead of:
sf"select * from sometable where name = '{userName}'"
you would write something like:
sql.query(SomeTable).filter_by(name=userName).all()
And I believe the same thing applies to HTML and just about anything else that has a complicated enough syntax that this idea would be useful for.
Second, if I had a strong reason to do something like this, I'd want to use a function that enabled me to add run-time sanity checking (at least during development and testing phase):
_html_(f"This is a <b><i>{adverb} bad</b></i> example.")
and in production that function would just return the value untouched.
--- Bruce _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/GVTWOF... Code of Conduct: http://python.org/psf/codeofconduct/
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/VRU4A7... Code of Conduct: http://python.org/psf/codeofconduct/
participants (15)
-
Alex Hall
-
Andrew Barnert
-
Antoine Rozo
-
Bruce Leban
-
Chris Angelico
-
David Mertz
-
jdveiga@gmail.com
-
Jonathan Fine
-
João Matos
-
Kyle Stanley
-
minecraft2048@gmail.com
-
Rob Cliffe
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Wes Turner