Reputation: 227
I have a table search
with a column vector
of type tsvector
. I'd like to use the SQLAlchemy core API to insert rows. Computing vector
requires 1) some processing in Python and 2) a call to to_tsvector
(a PG function).
I'm messing around with conn.execute(insert(Search), [{'vector': func.to_tsvector('here is a string')}])
but am getting
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'Function'
I'm trying to replicate the SQL query insert into search(vector) values (to_tsvector('here is a string'))
.
Upvotes: 0
Views: 691
Reputation: 9039
This seemed weird to me and I thought it was a bug but it is not a bug. zzzeek explains it in this discussion:
https://github.com/sqlalchemy/sqlalchemy/discussions/7640
You need to use
insert().values()
like session.execute(tbl.insert().values(values))
instead of directly using session.execute(tbl.insert(), values)
.
In case this gets lost you can perform the inserts like this example:
from sqlalchemy import (
create_engine,
Integer,
Text,
DateTime,
)
from sqlalchemy.schema import (
Column,
MetaData,
)
from sqlalchemy.sql import func, not_
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import Session
from sqlalchemy.dialects.postgresql import TSVECTOR
from sqlalchemy.exc import ProgrammingError
metadata = MetaData()
Base = declarative_base(metadata=metadata)
engine = create_engine('postgresql+psycopg2://username:password@/database', echo=False)
class Doc(Base):
__tablename__ = "docs"
id = Column(Integer, primary_key=True, index=True)
text = Column(Text, nullable=True)
vector = Column(TSVECTOR, nullable=True)
created_on = Column(DateTime, nullable=False)
metadata.create_all(engine)
doc_specs = [{
"text": "Frog jumping.",
}, {
"text": "Fish swimming.",
}, {
"text": "Bird flying.",
}, {
"text": "Cat jumping and flying.",
}]
with Session(engine) as session:
values = [{
"created_on": func.now(),
"text": spec["text"],
"vector": func.to_tsvector(spec["text"])
} for spec in doc_specs]
session.execute(Doc.__table__.insert().values(values))
session.commit()
print ("Matches")
for doc in session.query(Doc).filter(Doc.vector.match("jumping & flying")):
print (doc.id, doc.text, doc.vector)
print ("Misses")
for doc in session.query(Doc).filter(~Doc.vector.match("jumping & flying")):
print (doc.id, doc.text, doc.vector)
DROP DATABASE
CREATE DATABASE
Matches
4 Cat jumping and flying. 'cat':1 'fli':4 'jump':2
Misses
1 Frog jumping. 'frog':1 'jump':2
2 Fish swimming. 'fish':1 'swim':2
3 Bird flying. 'bird':1 'fli':2
Upvotes: 1