পোস্টগ্রিজ: ইতিমধ্যে বিদ্যমান না থাকলে INSERT


361

আমি পোস্টগ্রিজ ডাটাবেসে লিখতে পাইথন ব্যবহার করছি:

sql_string = "INSERT INTO hundred (name,name_slug,status) VALUES ("
sql_string += hundred + ", '" + hundred_slug + "', " + status + ");"
cursor.execute(sql_string)

তবে আমার কয়েকটি সারি অভিন্ন বলে আমি নিম্নলিখিত ত্রুটিটি পেয়েছি:

psycopg2.IntegrityError: duplicate key value  
  violates unique constraint "hundred_pkey"

এসকিউএল স্টেটমেন্ট না থাকলে আমি কীভাবে 'INSERT লিখব?

আমি এই প্রস্তাবিত মত জটিল বিবরণ দেখেছি:

IF EXISTS (SELECT * FROM invoices WHERE invoiceid = '12345')
UPDATE invoices SET billed = 'TRUE' WHERE invoiceid = '12345'
ELSE
INSERT INTO invoices (invoiceid, billed) VALUES ('12345', 'TRUE')
END IF

তবে প্রথমত, আমার যা প্রয়োজন তার জন্য কি এই ওভারকিল হয় এবং দ্বিতীয়ত, আমি কীভাবে সাধারণ স্ট্রিং হিসাবে তাদের একজনকে কার্যকর করতে পারি?


56
আপনি এই সমস্যাটিকে কীভাবে সমাধান করবেন তা বিবেচনা না করেই আপনার নিজের ক্যোয়ারীটি তৈরি করা উচিত নয়। আপনার ক্যোয়ারীতে প্যারামিটার ব্যবহার করুন এবং পৃথকভাবে মানগুলি পাস করুন; স্ট্যাকওভারফ্লো.com
থমাস ওয়াউটারস

3
কেন ব্যতিক্রম ধরা এবং তা উপেক্ষা করবেন না?
ম্যাথু মিচেল

5
পোস্টগ্রিস 9.5 (বর্তমানে বিটা 2 এ) হিসাবে নতুন বৈশিষ্ট্যটির মতো একটি বৈশিষ্ট্য রয়েছে, দেখুন: postgresql.org/docs/9.5/static/sql-insert.html#SQL-ON-CONFLICT
Ezequiel Moreno

2
আপনি কি এর জন্য একটি উত্তর গ্রহণ বিবেচনা করেছেন? =]
পুনরায় সাফল্য

উত্তর:


512

পোস্টগ্রেস 9.5 ( 2016-01-07 থেকে মুক্তি পেয়েছে) "আপসেট" কমান্ড অফার করে, এটি INSERT- এ ওএন কনফ্লিক্ট ধারা হিসাবেও পরিচিত :

INSERT ... ON CONFLICT DO NOTHING/UPDATE

এটি সমবর্তী ক্রিয়াকলাপটি ব্যবহার করার সময় আপনি চালাতে পারেন এমন অনেক সূক্ষ্ম সমস্যা সমাধান করে, যা অন্য কিছু উত্তর প্রস্তাব করে।


14
9.5 মুক্তি পেয়েছে।
ভাগ্যডায়োন্ড

2
@ তুষারজাইন পোস্টগ্র্রেএসকিউএল 9.5 এর পূর্বে আপনি একটি "পুরানো ফ্যাশন" ইউপিএসআরটি করতে পারেন (সিটিই সহ) তবে আপনি রেসের শর্ত নিয়ে সমস্যার সম্মুখীন হতে পারেন এবং এটি 9.5 স্টাইল হিসাবে প্রদর্শিত হবে না। আপনি বিশদ সম্পর্কে আরও জানতে চাইলে কিছু লিঙ্ক সহ এই ব্লগে (নীচে আপডেট হওয়া অংশে) আপলোড সম্পর্কে একটি ভাল বিশদ রয়েছে।
স্কাইগার্ড

16
তাদের প্রয়োজনীয়গুলির জন্য, এখানে দুটি সহজ উদাহরণ। (১) অন্য কোনও অস্তিত্ব না থাকলে ইনসার্ট - INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH') ON CONFLICT (did) DO NOTHING;(২) অন্য কোনও অস্তিত্ব না থাকলে ইনসার্ট আপডেট করুন - INSERT INTO distributors (did, dname) VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc') ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;এই উদাহরণগুলি ম্যানুয়াল থেকে - postgresql.org/docs/9.5/static/sql-insert.html
এ্যানিফর্মটাইওয়ান

13
একটি সতর্কতা / পার্শ্ব প্রতিক্রিয়া আছে। সিক্যুয়েন্স কলাম (সিরিয়াল বা বিগসিরিয়াল) সহ একটি সারণীতে, কোনও সারি প্রবেশ করা না হলেও প্রতিটি সন্নিবেশ প্রচেষ্টাতে ক্রমটি বাড়ানো হয় mented
গ্রজেগোর্স লুসজিও

2
এটি প্রকাশের দিকে ইঙ্গিত করার পরিবর্তে INSERT ডকুমেন্টেশনের সাথে আরও ভালভাবে সংযোগ স্থাপন করতে চাই। ডক লিঙ্ক: postgresql.org/docs/9.5/static/sql-insert.html
বোরজাগো

379

এসকিউএল স্টেটমেন্ট না থাকলে আমি কীভাবে 'INSERT লিখব?

পোস্টগ্রিজ এসকিউএলে শর্তসাপেক্ষ INSERT করার একটি দুর্দান্ত উপায় রয়েছে:

INSERT INTO example_table
    (id, name)
SELECT 1, 'John'
WHERE
    NOT EXISTS (
        SELECT id FROM example_table WHERE id = 1
    );

ক্যাভেট এই পদ্ধতিটি সমবর্তী লেখার ক্রিয়াকলাপের জন্য যদিও 100% নির্ভরযোগ্য নয় । তার মাঝে একটি খুব ছোট জাতি অবস্থা SELECTমধ্যে NOT EXISTS-যোগ বিরোধী আধা এবং INSERTনিজেই। এটি এ জাতীয় পরিস্থিতিতে ব্যর্থ হতে পারে।


এটি "নাম"-ফিল্ডের একটি অনন্য বাধা আছে তা ধরে নেওয়া কতটা নিরাপদ? এটি কি কখনও অনন্য-লঙ্ঘনের সাথে ব্যর্থ হবে?
অগ্নসফট

2
এটি কাজ করে। একমাত্র সমস্যাটি আমার অনুমানের সংযোগটি: যদি কেউ টেবিলটি এমনভাবে পরিবর্তন করে যে আরও কলাম অনন্য। সেক্ষেত্রে সমস্ত স্ক্রিপ্ট অবশ্যই সংশোধন করতে হবে। এটি করার আরও সাধারণ উপায় থাকলে খুব ভাল লাগবে ...
উইলিম ভ্যান ওনসেম

1
Itোকানো হয়েছে কিনা তা RETURNS idউদাহরণস্বরূপ এটির সাথে ব্যবহার করা সম্ভব id?
অলিভিয়ার পন্স

2
@ অলিভিয়ারপোনস হ্যাঁ, এটি সম্ভব। যোগ RETURNING idএবং ক্যোয়ারী এবং যদি কোন সারি ঢোকানো হয়েছে এটা, হয় একটি নতুন সারি আইডি অথবা কিছুই ফিরে আসবে।
অ্যালেক্সএম

4
আমি এটি অবিশ্বাস্য বলে মনে করেছি। এটি প্রদর্শিত হয় পোস্টগ্র্রেস কখনও কখনও সন্নিবেশটি সম্পাদন করে এটি নির্বাচনটি কার্যকর করার আগে এবং রেকর্ডটি এখনও সন্নিবেশ না করা সত্ত্বেও আমি একটি সদৃশ কী লঙ্ঘনের সাথে শেষ করি। অন ​​কনফ্লিক্ট সহ সংস্করণ => 9.5 ব্যবহার করার চেষ্টা করুন।
মাইকেল সিলভার

51

একটি পদ্ধতির মধ্যে হ'ল আপনার সমস্ত তথ্য সন্নিবেশ করানোর জন্য একটি অ-সীমাবদ্ধ (কোনও অনন্য সূচী নয়) সারণী তৈরি করা এবং আপনার সারণিতে আপনার সন্নিবেশ করার জন্য এটির থেকে একটি পৃথক পৃথক কাজ করুন।

সুতরাং উচ্চ স্তর হতে হবে। আমি ধরে নিচ্ছি যে তিনটি কলামই আমার উদাহরণে স্বতন্ত্র, সুতরাং স্টিপি 3 পরিবর্তনের জন্য নয়টি প্রস্থান করুন পরিবর্তনের জন্য কেবলমাত্র একশ টেবিলের অনন্য কলামে যোগদান করুন।

  1. অস্থায়ী সারণী তৈরি করুন। ডক্স এখানে দেখুন ।

    CREATE TEMPORARY TABLE temp_data(name, name_slug, status);
  2. টেম্প টেবিলের মধ্যে তথ্য প্রবেশ করুন।

    INSERT INTO temp_data(name, name_slug, status); 
  3. টেম্প টেবিলটিতে কোনও সূচক যুক্ত করুন।

  4. প্রধান টেবিল .োকান।

    INSERT INTO hundred(name, name_slug, status) 
        SELECT DISTINCT name, name_slug, status
        FROM hundred
        WHERE NOT EXISTS (
            SELECT 'X' 
            FROM temp_data
            WHERE 
                temp_data.name          = hundred.name
                AND temp_data.name_slug = hundred.name_slug
                AND temp_data.status    = status
        );

3
এটি সর্বাধিক সন্নিবেশ করার জন্য আমি সবচেয়ে দ্রুততম পন্থা যখন সারিটি ইতিমধ্যে বিদ্যমান কিনা তা আমি জানি না।
nate c

'এক্স' নির্বাচন করবেন? কেউ স্পষ্ট করতে পারেন? এটি কেবলমাত্র একটি নির্বাচনী বিবৃতি সরাসরি: SELECT name,name_slug,statusবা*
রবার্থটুইঙ্গার

3
সংযুক্ত subquery সন্ধান করুন। 'এক্স' 1 বা এমনকি 'স্যাডক্লাউন' এ পরিবর্তিত হতে পারে। এসকিউএলকে কিছু হওয়া দরকার এবং 'এক্স' ব্যবহার করার একটি সাধারণ জিনিস। এটি ছোট এবং এটি স্পষ্ট করে তোলে যে একটি পারস্পরিক সম্পর্কযুক্ত সাবকোয়ারি ব্যবহৃত হচ্ছে এবং এসকিউএল যা প্রয়োজন তার প্রয়োজনীয়তা পূরণ করে।
কুবেরচাঁন

আপনি উল্লেখ করেছেন "আপনার সমস্ত তথ্য intoোকান (অস্থায়ী টেবিলটি ধরে রেখে) এবং এর থেকে একটি পৃথক নির্বাচন করুন"। সেক্ষেত্রে এটা কি হওয়া উচিত নয় SELECT DISTINCT name, name_slug, status FROM temp_data?
gibbz00

17

দুর্ভাগ্যবশত, PostgreSQLসমর্থন তন্ন তন্ন MERGEনা ON DUPLICATE KEY UPDATE, তাই আপনি দুই বিবৃতি এটা করতে হবে:

UPDATE  invoices
SET     billed = 'TRUE'
WHERE   invoices = '12345'

INSERT
INTO    invoices (invoiceid, billed)
SELECT  '12345', 'TRUE'
WHERE   '12345' NOT IN
        (
        SELECT  invoiceid
        FROM    invoices
        )

আপনি এটিকে কোনও ফাংশনে আবদ্ধ করতে পারেন:

CREATE OR REPLACE FUNCTION fn_upd_invoices(id VARCHAR(32), billed VARCHAR(32))
RETURNS VOID
AS
$$
        UPDATE  invoices
        SET     billed = $2
        WHERE   invoices = $1;

        INSERT
        INTO    invoices (invoiceid, billed)
        SELECT  $1, $2
        WHERE   $1 NOT IN
                (
                SELECT  invoiceid
                FROM    invoices
                );
$$
LANGUAGE 'sql';

এবং কেবল এটি কল করুন:

SELECT  fn_upd_invoices('12345', 'TRUE')

1
আসলে, এটি কাজ করে না: আমি INSERT INTO hundred (name, name_slug, status) SELECT 'Chichester', 'chichester', NULL WHERE 'Chichester' NOT IN (SELECT NAME FROM hundred);বহুবার কল করতে পারি এবং এটি সারিটি সন্নিবেশ করে রাখে keeps
এপি 257

1
@ AP257: CREATE TABLE hundred (name TEXT, name_slug TEXT, status INT); INSERT INTO hundred (name, name_slug, status) SELECT 'Chichester', 'chichester', NULL WHERE 'Chichester' NOT IN (SELECT NAME FROM hundred); INSERT INTO hundred (name, name_slug, status) SELECT 'Chichester', 'chichester', NULL WHERE 'Chichester' NOT IN (SELECT NAME FROM hundred); SELECT * FROM hundred। একটি রেকর্ড আছে।
কাসনসুই

12

আপনি ভ্যালু ব্যবহার করতে পারেন - পোস্টগ্র্রেসে উপলভ্য:

INSERT INTO person (name)
    SELECT name FROM person
    UNION 
    VALUES ('Bob')
    EXCEPT
    SELECT name FROM person;

12
ব্যক্তির কাছ থেকে নাম নির্বাচন করুন <--- যদি ব্যক্তিতে এক বিলিয়ন সারি থাকে?
হেনলি চিউ

1
আমি মনে করি এটি সমস্যা সমাধানের একটি দুর্দান্ত দ্রুত উপায়, তবে কেবলমাত্র যখন আপনি নিশ্চিত হন যে উত্স টেবিলটি কখনই বিশাল আকার ধারণ করবে না। আমি একটি টেবিল পেয়েছি যার মধ্যে 1000 টিরও বেশি সারি থাকবে না, তাই আমি এই সমাধানটি ব্যবহার করতে পারি।
লিওনার্ড

বাহ, এটা ঠিক আমার প্রয়োজন ছিল। আমি উদ্বিগ্ন ছিলাম আমাকে একটি ফাংশন বা একটি টেম্প টেবিল তৈরি করতে হবে, তবে এটি সমস্ত কিছু অন্তর্ভুক্ত করে - আপনাকে ধন্যবাদ!
অমলগোভিনাস

8

আমি জানি এই প্রশ্নটি কিছুক্ষণ আগে থেকেই হয়েছিল তবে ভেবেছিল এটি কারও সাহায্য করবে। আমি মনে করি এটি করার সবচেয়ে সহজ উপায়টি একটি ট্রিগার মাধ্যমে। উদাহরণ:

Create Function ignore_dups() Returns Trigger
As $$
Begin
    If Exists (
        Select
            *
        From
            hundred h
        Where
            -- Assuming all three fields are primary key
            h.name = NEW.name
            And h.hundred_slug = NEW.hundred_slug
            And h.status = NEW.status
    ) Then
        Return NULL;
    End If;
    Return NEW;
End;
$$ Language plpgsql;

Create Trigger ignore_dups
    Before Insert On hundred
    For Each Row
    Execute Procedure ignore_dups();

এই কোডটি একটি পিএসকিএল প্রম্পট থেকে কার্যকর করুন (বা তবে আপনি সরাসরি ডাটাবেসে কোয়েরিগুলি চালাতে চান)। তারপরে আপনি পাইথন থেকে স্বাভাবিক হিসাবে সন্নিবেশ করতে পারেন। উদাহরণ:

sql = "Insert Into hundreds (name, name_slug, status) Values (%s, %s, %s)"
cursor.execute(sql, (hundred, hundred_slug, status))

নোট করুন যে @ থমাস_উইটারগুলি ইতিমধ্যে উল্লিখিত হয়েছে, উপরের কোডটি স্ট্রিংকে মনযোগ দেওয়ার চেয়ে পরামিতিগুলির সুবিধা গ্রহণ করে।


অন্য কেউ যদি ডক্স থেকেও ভাবছেন : "সারি-স্তরের ট্রিগারগুলি এই সারিটির বাকি অপারেশনটি এড়িয়ে যাওয়ার জন্য ট্রিগার ম্যানেজারকে সংকেত দেওয়ার জন্য ফিরে যেতে পারে (অর্থাত, পরবর্তী ট্রিগারগুলি বহিস্কার করা হয়নি, এবং INSERT / UPDATE) / মুছে ফেলা এই সারির জন্য ঘটে না) যদি কোনও ননলাল মান ফিরে আসে তবে অপারেশনটি এই সারির মান দিয়ে এগিয়ে যায়। "
পিট

ঠিক এই উত্তরটি আমি খুঁজছিলাম। নির্বাচন কোডের পরিবর্তে ফাংশন + ট্রিগার ব্যবহার করে ক্লিন কোড। +1
জ্যাসেক ক্রাভজাইক

আমি এই উত্তরটি পছন্দ করি, ফাংশন এবং ট্রিগার ব্যবহার করি। ফাংশন এবং ট্রিগারগুলি ব্যবহার করে অচলাবস্থা ভাঙার জন্য আমি এখন অন্য একটি উপায় খুঁজে পেয়েছি ...
সুকমা সাপুত্র

7

স্নাতকোত্তর INSERT করার পোস্টারগ্রাহীকিউএইউএল কোয়েরি ব্যবহার করে করার একটি দুর্দান্ত উপায় রয়েছে: লাইক:

WITH a as(
select 
 id 
from 
 schema.table_name 
where 
 column_name = your_identical_column_value
)
INSERT into 
 schema.table_name
(col_name1, col_name2)
SELECT
    (col_name1, col_name2)
WHERE NOT EXISTS (
     SELECT
         id
     FROM
         a
        )
  RETURNING id 

7

এটি হ'ল সমস্যাটি হ'ল আমার সংস্করণটি 9.5

এবং আমি এটি নীচে এসকিউএল কোয়েরি দিয়ে সমাধান করি।

INSERT INTO example_table (id, name)
SELECT 1 AS id, 'John' AS name FROM example_table
WHERE NOT EXISTS(
            SELECT id FROM example_table WHERE id = 1
    )
LIMIT 1;

আশা করি এর সাথে সংস্করণ> = 9.5 এর একই সমস্যা রয়েছে এমন কাউকে সহায়তা করবে।

পড়ার জন্য ধন্যবাদ.


5

অন্তর্ভুক্ত .. যেখানে অস্তিত্ব নেই ভাল পদ্ধতির। এবং বর্ণের পরিস্থিতি লেনদেনের "খাম" দ্বারা এড়ানো যায়:

BEGIN;
LOCK TABLE hundred IN SHARE ROW EXCLUSIVE MODE;
INSERT ... ;
COMMIT;

2

এটি নিয়ম সহ সহজ:

CREATE RULE file_insert_defer AS ON INSERT TO file
WHERE (EXISTS ( SELECT * FROM file WHERE file.id = new.id)) DO INSTEAD NOTHING

তবে এটি সমকালীন লেখাগুলিতে ব্যর্থ হয় ...


1

সর্বাধিক উপন্যাসের সাথে (জন দো থেকে) যোগাযোগ আমার পক্ষে কোনওভাবেই কাজ করে তবে প্রত্যাশিত 422 সারি থেকে আমার ক্ষেত্রে আমি কেবল 180 পেয়েছি get আমি কোনও ভুল খুঁজে পেলাম না এবং কোনও ত্রুটিও নেই, তাই আমি আলাদা চেয়েছিলাম সহজ পদ্ধতির

ন্যায়বিচারের IF NOT FOUND THENপরে ব্যবহার করা SELECTআমার পক্ষে পুরোপুরি কাজ করে।

( পোস্টগ্রাইএসকিউএল ডকুমেন্টেশনে বর্ণিত )

ডকুমেন্টেশন থেকে উদাহরণ:

SELECT * INTO myrec FROM emp WHERE empname = myname;
IF NOT FOUND THEN
  RAISE EXCEPTION 'employee % not found', myname;
END IF;

1

সাইকোপস কার্সার ক্লাসে রাইটকাউন্টের বৈশিষ্ট্য রয়েছে

এই কেবল পঠনযোগ্য বৈশিষ্ট্যটি সুনির্দিষ্টভাবে সর্বাধিক সম্পাদনকারী * () দ্বারা উত্পাদিত DQL বিবৃতি (SELECT এর মতো) বা প্রভাবিত হয়েছে (UPML বা INSERT এর মতো ডিএমএল বিবৃতিগুলির জন্য) সুনির্দিষ্ট করে।

সুতরাং আপনি প্রথম আপডেটের চেষ্টা করতে পারেন এবং সারণি কেবলমাত্র 0 সংখ্যার অন্তর্ভুক্ত করে।

তবে আপনার ডেটাবেজে ক্রিয়াকলাপের স্তরের উপর নির্ভর করে আপনি আপডেট এবং INSERT এর মধ্যে এমন একটি দৌড়ের শর্তটি হিট করতে পারেন যেখানে অন্য কোনও প্রক্রিয়া অন্তর্বর্তীতে সেই রেকর্ড তৈরি করতে পারে।


সম্ভবত এই কোয়েরিগুলি কোনও লেনদেনে মুড়ে ফেলা জাতিদের শর্তকে হ্রাস করবে।
ড্যানিয়েল লিয়ন্স

ধন্যবাদ, সত্যই সহজ এবং পরিষ্কার সমাধান
আলেকজান্ডার মালফাইট

1

আপনার কলাম "শত" প্রাথমিক কী হিসাবে সংজ্ঞায়িত হয়েছে বলে মনে হয় এবং তাই অনন্য হতে হবে যা এটি নয়। সমস্যাটি নয়, এটি আপনার ডেটা সহ।

আমি আপনাকে প্রাথমিক কীটি হ্যান্ডল করতে সিরিয়াল টাইপ হিসাবে একটি আইডি sertোকানোর পরামর্শ দিচ্ছি


1

আপনি যদি বলেন যে আপনার অনেকগুলি সারি একরকম হয় তবে আপনি অনেক বার পরীক্ষা করে শেষ করবেন। আপনি সেগুলি প্রেরণ করতে পারেন এবং ডাটাবেসগুলি নির্ধারিত হবে এটি নীচে CONFLICT ধারা সহ সন্নিবেশ করানো হয়েছে কি না

  INSERT INTO Hundred (name,name_slug,status) VALUES ("sql_string += hundred  
  +",'" + hundred_slug + "', " + status + ") ON CONFLICT ON CONSTRAINT
  hundred_pkey DO NOTHING;" cursor.execute(sql_string);

0

আমি অনুরূপ সমাধানের সন্ধান করছিলাম, এসকিউএল অনুসন্ধান করার চেষ্টা করছিলাম যা পোস্টগ্রেএসকিউএল এবং এইচএসকিউএলডিবি-তে কাজ করে। (এইচএসকিউএলডিবিই এটিকে কঠিন করে তুলেছিল)) আপনার উদাহরণকে ভিত্তি হিসাবে ব্যবহার করে, এটি অন্য যে কোনও জায়গায় আমি খুঁজে পেয়েছি format

sql = "INSERT INTO hundred (name,name_slug,status)"
sql += " ( SELECT " + hundred + ", '" + hundred_slug + "', " + status
sql += " FROM hundred"
sql += " WHERE name = " + hundred + " AND name_slug = '" + hundred_slug + "' AND status = " + status
sql += " HAVING COUNT(*) = 0 );"

-1

এখানে একটি জেনেরিক পাইথন ফাংশন রয়েছে যা একটি টেবিলের নাম, কলাম এবং মান দেয়, পোস্টগ্র্যাসকিএল-এর সমতুল্য উত্সাহ উত্পন্ন করে।

আমদানি জেসন

def upsert(table_name, id_column, other_columns, values_hash):

    template = """
    WITH new_values ($$ALL_COLUMNS$$) as (
      values
         ($$VALUES_LIST$$)
    ),
    upsert as
    (
        update $$TABLE_NAME$$ m
            set
                $$SET_MAPPINGS$$
        FROM new_values nv
        WHERE m.$$ID_COLUMN$$ = nv.$$ID_COLUMN$$
        RETURNING m.*
    )
    INSERT INTO $$TABLE_NAME$$ ($$ALL_COLUMNS$$)
    SELECT $$ALL_COLUMNS$$
    FROM new_values
    WHERE NOT EXISTS (SELECT 1
                      FROM upsert up
                      WHERE up.$$ID_COLUMN$$ = new_values.$$ID_COLUMN$$)
    """

    all_columns = [id_column] + other_columns
    all_columns_csv = ",".join(all_columns)
    all_values_csv = ','.join([query_value(values_hash[column_name]) for column_name in all_columns])
    set_mappings = ",".join([ c+ " = nv." +c for c in other_columns])

    q = template
    q = q.replace("$$TABLE_NAME$$", table_name)
    q = q.replace("$$ID_COLUMN$$", id_column)
    q = q.replace("$$ALL_COLUMNS$$", all_columns_csv)
    q = q.replace("$$VALUES_LIST$$", all_values_csv)
    q = q.replace("$$SET_MAPPINGS$$", set_mappings)

    return q


def query_value(value):
    if value is None:
        return "NULL"
    if type(value) in [str, unicode]:
        return "'%s'" % value.replace("'", "''")
    if type(value) == dict:
        return "'%s'" % json.dumps(value).replace("'", "''")
    if type(value) == bool:
        return "%s" % value
    if type(value) == int:
        return "%s" % value
    return value


if __name__ == "__main__":

    my_table_name = 'mytable'
    my_id_column = 'id'
    my_other_columns = ['field1', 'field2']
    my_values_hash = {
        'id': 123,
        'field1': "john",
        'field2': "doe"
    }
    print upsert(my_table_name, my_id_column, my_other_columns, my_values_hash)

-8

সমাধানটি সহজ, তবে তাত্ক্ষণিকভাবে নয়।
আপনি যদি এই নির্দেশিকাটি ব্যবহার করতে চান তবে আপনাকে অবশ্যই ডিবিতে একটি পরিবর্তন করতে হবে:

ALTER USER user SET search_path to 'name_of_schema';

এই পরিবর্তনগুলির পরে "INSERT" সঠিকভাবে কাজ করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.