使用SQLAlchemy执行带有命名参数的SQL语句。

huangapple go评论66阅读模式
英文:

Using SQLAlchemy to execute an SQL statement with named parameters

问题

无法原始插入带有SQLalchemy的字典列表吗?

import os
import sqlalchemy
import pandas as pd

def connect_unix_socket() -> sqlalchemy.engine:
    db_user = os.environ["DB_USER"]
    db_pass = os.environ["DB_PASS"]
    db_name = os.environ["DB_NAME"]
    unix_socket_path = os.environ["INSTANCE_UNIX_SOCKET"]
    return sqlalchemy.create_engine(
        sqlalchemy.engine.url.URL.create(
            drivername="postgresql+pg8000",
            username=db_user,
            password=db_pass,
            database=db_name,
            query={"unix_sock": f"{unix_socket_path}/.s.PGSQL.5432"},
        )
    )

def _insert_ecoproduct(df: pd.DataFrame) -> None:
    db = connect_unix_socket()
    db_matching = {
        'gtin': 'ecoproduct_id',
        'ITEM_NAME_AS_IN_MARKETPLACE': 'ecoproductname',
        'ITEM_WEIGHT_WITH_PACKAGE_KG': 'ecoproductweight',
        'ITEM_HEIGHT_CM': 'ecoproductlength',
        'ITEM_WIDTH_CM': 'ecoproductwidth',
        'test_gtin': 'gtin_test',
        'batteryembedded': 'batteryembedded'
    }
    df = df[db_matching.keys()]
    df.rename(columns=db_matching, inplace=True)
    data = df.to_dict(orient='records')
    sql_query = """INSERT INTO ecoproducts(
            ecoproduct_id,
            ecoproductname,
            ecoproductweight,
            ecoproductlength,
            ecoproductwidth,
            gtin_test,
            batteryembedded)
        VALUES (%(ecoproduct_id)s, %(ecoproductname)s,%(ecoproductweight)s,%(ecoproductlength)s,
            %(ecoproductwidth)s,%(gtin_test)s,%(batteryembedded)s) 
        ON CONFLICT(ecoproduct_id) DO NOTHING;"""

    with db.connect() as conn:
        result = conn.exec_driver_sql(sql_query, data)
        print(f"{result.rowcount} new rows were inserted.")

我一直遇到这个错误:

这里可能是因为pg8000方言无法映射参数吗?或者我应该使用psycopg2吗?

问题在哪里?

编辑1:查看数据变量的详细信息:

print(data)
print(type(data))
[{'ecoproduct_id': '6941487202157', 'ecoproductname': 'HUAWEI FreeBuds Pro Bluetooth sans Fil ', 'ecoproductweight': '4', 'ecoproductlength': '0.220', 'ecoproductwidth': '0.99', 'gtin_test': False, 'batteryembedded': 0}]
<class 'list'>
英文:

Why can't I raw insert a list of dicts with SQLalchemy ?

import os
import sqlalchemy
import pandas as pd

def connect_unix_socket() -&gt; sqlalchemy.engine:
	db_user = os.environ[&quot;DB_USER&quot;]
	db_pass = os.environ[&quot;DB_PASS&quot;]
	db_name = os.environ[&quot;DB_NAME&quot;]
	unix_socket_path = os.environ[&quot;INSTANCE_UNIX_SOCKET&quot;]
	return sqlalchemy.create_engine(
		sqlalchemy.engine.url.URL.create(
			drivername=&quot;postgresql+pg8000&quot;,
			username=db_user,
			password=db_pass,
			database=db_name,
			query={&quot;unix_sock&quot;: f&quot;{unix_socket_path}/.s.PGSQL.5432&quot;},
		)
	)

def _insert_ecoproduct(df: pd.DataFrame) -&gt; None:
	db = connect_unix_socket()
	db_matching = {
		&#39;gtin&#39;: &#39;ecoproduct_id&#39;,
		&#39;ITEM_NAME_AS_IN_MARKETPLACE&#39; : &#39;ecoproductname&#39;,
		&#39;ITEM_WEIGHT_WITH_PACKAGE_KG&#39; : &#39;ecoproductweight&#39;,
		&#39;ITEM_HEIGHT_CM&#39; : &#39;ecoproductlength&#39;,
		&#39;ITEM_WIDTH_CM&#39; : &#39;ecoproductwidth&#39;,
		&#39;test_gtin&#39; : &#39;gtin_test&#39;,
		&#39;batteryembedded&#39; : &#39;batteryembedded&#39;
	}
	df = df[db_matching.keys()]
	df.rename(columns=db_matching, inplace=True)
	data = df.to_dict(orient=&#39;records&#39;)
	sql_query = &quot;&quot;&quot;INSERT INTO ecoproducts(
			ecoproduct_id,
			ecoproductname,
			ecoproductweight,
			ecoproductlength,
			ecoproductwidth,
			gtin_test,
			batteryembedded)
		VALUES (%(ecoproduct_id)s, %(ecoproductname)s,%(ecoproductweight)s,%(ecoproductlength)s,
			%(ecoproductwidth)s,%(gtin_test)s,%(batteryembedded)s) 
		ON CONFLICT(ecoproduct_id) DO NOTHING;&quot;&quot;&quot;

	with db.connect() as conn:
		result = conn.exec_driver_sql(sql_query, data)
		print(f&quot;{result.rowcount} new rows were inserted.&quot;)

I keep having this error :
使用SQLAlchemy执行带有命名参数的SQL语句。

Is it possible to map parameters with th dialect pg8000 ? Or maybe I should use psycopg2 ?

What is the problem here ?

EDIT 1: see variable data details :

print(data)
print(type(data))
[{&#39;ecoproduct_id&#39;: &#39;6941487202157&#39;, &#39;ecoproductname&#39;: &#39;HUAWEI FreeBuds Pro Bluetooth sans Fil &#39;, &#39;ecoproductweight&#39;: &#39;4&#39;, &#39;ecoproductlength&#39;: &#39;0.220&#39;, &#39;ecoproductwidth&#39;: &#39;0.99&#39;, &#39;gtin_test&#39;: False, &#39;batteryembedded&#39;: 0}]
&lt;class &#39;list&#39;&gt;

答案1

得分: 1

是的,使用SQLAlchemy的text()对象允许我们在底层DBAPI不支持的情况下使用命名参数来映射参数。

import sqlalchemy as sa

sql_query = &quot;&quot;&quot;\
INSERT INTO ecoproducts(
    ecoproduct_id,
    ecoproductname,
    ecoproductweight,
    ecoproductlength,
    ecoproductwidth,
    gtin_test,
    batteryembedded)
VALUES (
    :ecoproduct_id,
    :ecoproductname,
    :ecoproductweight,
    :ecoproductlength,
    :ecoproductwidth,
    :gtin_test,
    :batteryembedded) 
ON CONFLICT(ecoproduct_id) DO NOTHING;
&quot;&quot;&quot;
result = conn.execute(sa.text(sql_query), data)
英文:

> Is it possible to map [named] parameters with th (sic) dialect pg8000 ?

Yes. Using a SQLAlchemy text() object allows us to use named parameters even if the underlying DBAPI does not.

import sqlalchemy as sa

sql_query = &quot;&quot;&quot;\
INSERT INTO ecoproducts(
    ecoproduct_id,
    ecoproductname,
    ecoproductweight,
    ecoproductlength,
    ecoproductwidth,
    gtin_test,
    batteryembedded)
VALUES (
    :ecoproduct_id,
    :ecoproductname,
    :ecoproductweight,
    :ecoproductlength,
    :ecoproductwidth,
    :gtin_test,
    :batteryembedded) 
ON CONFLICT(ecoproduct_id) DO NOTHING;
&quot;&quot;&quot;
result = conn.execute(sa.text(sql_query), data)

huangapple
  • 本文由 发表于 2023年1月9日 18:50:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056198.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定