Sqlalchemy postgresql 保留关键字作为列名无法插入

问题描述 投票:0回答:1

我有一个列名为“collation”的表,我无法更改其架构。 我使用以下代码片段生成了一些要插入到该表中的数据:

from sqlalchemy.dialects import postgresql

data = [{"collation": "foo"}, {"collation":"bar"}]
stmt = postgresql.insert(table).values(data)
with engine.connect() as conn:
    conn.execute(stmt.compile(dialect=postgresql.dialect()))
    conn.commit()

我收到以下错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "collation"
LINE 1: ... (id, column_name, common_data_type, default_val, collation,...
                                                             ^

我尝试用

quoted_string("collation",True)
替换列名称,但仍然遇到相同的错误。 如何让 sqlalchemy 生成在列周围带引号的插入查询
collation

postgresql sqlalchemy
1个回答
0
投票

quote=True
传递给
Column()
似乎有效。我不确定你的模式来自哪里,但它似乎适用于 ORM
class
并且还具有
Table()
定义。

import os

from sqlalchemy import (
    Column,
    String,
    BigInteger,
    create_engine,
    Table,
)
from sqlalchemy.sql import (
    select,
    insert,
)
from sqlalchemy.orm import (
    declarative_base,
    Session,
)


def get_engine(env):
    return create_engine(f"postgresql+psycopg://{env['DB_USER']}:{env['DB_PASSWORD']}@{env['DB_HOST']}:{env['DB_PORT']}/{env['DB_NAME']}", echo=True)

Base = declarative_base()

class Sample(Base):
    __tablename__ = 'samples'
    id = Column(BigInteger, primary_key=True)
    collation = Column(name="collation", type_=String, nullable=False, quote=True)


texts_t = Table(
    "texts",
    Base.metadata,
    Column('id', BigInteger, primary_key=True),
    Column('collation', type_=String, nullable=False, quote=True)
    )

def main():
    engine = get_engine(os.environ)

    with engine.begin() as conn:
        Base.metadata.create_all(conn)

        populate(conn)

        query(conn)


def query(conn):
    with Session(conn) as session:
        for sample in session.scalars(select(Sample)):
            print ('SAMPLE', sample.id, sample.collation)
        for row in session.execute(select(texts_t)):
            print ('TEXTS', row[0], row[1])


def populate(conn):
    with Session(conn) as session:
        session.add(Sample(collation='en_us_ca_morro_bay'))
        session.add(Sample(collation='en_us_ca_santa_margarita'))
        session.execute(insert(texts_t), [{"collation": "en_us_ca_morro_bay_1"}, {"collation": "en_us_ca_santa_margarita_1"}])
        session.commit()


if __name__ == '__main__':
    main()

© www.soinside.com 2019 - 2024. All rights reserved.