-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support postgresql VALUES lists #23
Comments
So hugsql has stuff like this: This kind of syntax would require pugsql parsing the sql itself, as opposed to leaning entirely on sqlalchemy to do that. I'm definitely down to do this if it becomes necessary. I've started down the road of implementing that a few times, but every time I've done this I've figured out some way to just let sqlalchemy do the hard part. Multi-row inserts are very similar to this: And I'm wondering if that approach also works here.
If there's a way it works but that way is weird/inconsistent with the insert usage of |
I wondered the same myself, but couldn't see how to do it, without inferring the intended use by the user... and that seemed difficult (impossible?), or at least too magical. I'm new to pugsql (and never used hugsql), but perhaps parameter types are needed, to make it clear how these should be rendered: https://www.hugsql.org/#param-types There're other types of collections that may need to be rendered too, such as arrays, From the PostgreSQL documentation on value delimiters:
So for collections it seems the delimiter may differ, as does the enclosing symbol. Not sure what various types other DBs use. Hugsql appears to use the correct type depending on the clojure data type used (untested), but also supports specifying what type a param is. Is this approach possible with pugsql? Would that still allow it to use sqla to do the hard part? |
Yeah, you are probably right about this. Seems worth parsing the sql, although that’s gonna be a significant addition. |
I'am not sure if i understand you correctly but it seems that sqla support what pugsql need here. import sqlalchemy
args = [1, 2, 3]
raw_sql = "SELECT * FROM table WHERE data IN :values"
query = sqlalchemy.text(raw_sql).bindparams(values=tuple(args))
conn.engine.execute(query) |
Hi, nice library :) I have extended pugsql with this snippet to make use of many values in simple inserts. """
Adds a insert statement to a Module that allows inserting multiple values per query
"""
import pugsql
import sqlalchemy as sa
class FastInsertStatement(pugsql.statement.Statement):
def __init__(self, name: str, table_name: str, column_names: list[str]):
columns_str = ",".join(column_names)
params_str = ",".join([f":{c}" for c in column_names])
sql = f"INSERT INTO {table_name} ({columns_str}) VALUES ({params_str})"
insert_stmt = sa.table(
table_name, *[sa.column(c) for c in column_names]
).insert()
super().__init__(
name, sql, "this is a fast insert statement", pugsql.parser._insert, None
)
self._table_name = table_name
self._column_names = column_names
self._slow_text = self._text
self._text = insert_stmt
def _param_names(self):
def kfn(p):
return self.sql.index(":" + p)
return sorted(self._slow_text._bindparams.keys(), key=kfn)
def add_fast_insert_statement(
module: pugsql.compiler.Module,
statement_name: str,
table_name: str,
column_names: list[str],
) -> None:
stmt = FastInsertStatement(statement_name, table_name, column_names)
if hasattr(module, statement_name):
if statement_name not in module._statements:
raise ValueError(
f'Error adding FastInsertStatement - the function name "{statement_name}"'
" is reserved. Please choose another name."
)
raise ValueError(
"Error adding FastInsertStatement - there already exists a Statement with "
f"the name {statement_name} in {getattr(module, statement_name).filename}"
)
stmt.set_module(module)
setattr(module, statement_name, stmt)
module._statements[statement_name] = stmt |
Example:
See https://www.postgresql.org/docs/9.5/queries-values.html
Is there a way to make pugsql generic enough to generate any SQL, regardless of whether or not the specific driver supports it, thus solving this in a more generic way?
The text was updated successfully, but these errors were encountered: