এসকিউএএলএলচেমি ওআরএম সহ বাল্ক সন্নিবেশ


130

এসকিউএএলএলচেমি প্রতিটি স্বতন্ত্র বস্তু .োকানোর চেয়ে বাল্ক সন্নিবেশ করার কী উপায় আছে? অর্থাত,

করছেন:

INSERT INTO `foo` (`bar`) VALUES (1), (2), (3)

বরং:

INSERT INTO `foo` (`bar`) VALUES (1)
INSERT INTO `foo` (`bar`) VALUES (2)
INSERT INTO `foo` (`bar`) VALUES (3)

আমি সবেমাত্র কাঁচা এসকিএল এর পরিবর্তে স্কেলচেমি ব্যবহার করতে কিছু কোড রূপান্তর করেছি এবং যদিও এটির সাথে কাজ করা এখন খুব ভাল তবে এটি এখন ধীর বলে মনে হচ্ছে (10 এর একটি ফ্যাক্টর পর্যন্ত), আমি ভাবছি যে এটি কারণ কিনা।

আমি আরও বেশি দক্ষতার সাথে সেশন ব্যবহার করে পরিস্থিতির উন্নতি করতে পারি be এই মুহুর্তে আমি কিছু স্টাফ যুক্ত করেছি তার পরে autoCommit=Falseএবং করব session.commit()। যদিও ডিবি অন্য কোথাও পরিবর্তন করা হয়েছে তা যদি ডেটাটিকে বাসি করে দেবে বলে মনে হয়, যেমন আমি নতুন জিজ্ঞাসা করি তাও আমি পুরানো ফলাফলগুলি ফিরে পাই?

আপনার সাহায্যের জন্য ধন্যবাদ!


1
এটি সাহায্য করতে পারে: স্ট্যাকওভারফ্লো.com
সান ভাইয়েরা

1
নিক, আমি বুঝতে পারি এটি খুব পুরানো পোস্ট। "এসকিউএএলএলচেমি ওআরএম সহ একাধিক রেকর্ড সন্নিবেশ" এর মতো সঠিক কিছুতে শিরোনামটি আপডেট করা কি সম্ভব হবে ? আপনি সরবরাহ করেছেন এমন একাধিক রেকর্ড সন্নিবেশ বিবৃতি ডাটাবেস স্তরে বাল্ক-লোডিং অপারেশন থেকে একেবারে পৃথক। বাল্ক সন্নিবেশগুলি 1k + ডেটা আপলোডের জন্য তৈরি করা হয়, সাধারণত বড় ডেটাसेट থেকে এবং অ্যাপ্লিকেশন পরিচালকদের দ্বারা সম্পন্ন করা হয়, আরএসটি অপারেশন বা অ্যাপ্লিকেশন স্তর কোড নয় .... আসুন আমাদের নামকরণ সঠিকভাবে ব্যবহার করুন use
W4t3randWind

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

উত্তর:


173

এসকিউএলএলচেমি সংস্করণে এটি চালু করেছিল 1.0.0:

বাল্ক অপারেশন - এসকিউএএলএলএকমি ডক্স

এই অপারেশনগুলির সাহায্যে আপনি এখন বাল্ক সন্নিবেশ বা আপডেটগুলি করতে পারেন!

উদাহরণস্বরূপ, আপনি এটি করতে পারেন:

s = Session()
objects = [
    User(name="u1"),
    User(name="u2"),
    User(name="u3")
]
s.bulk_save_objects(objects)
s.commit()

এখানে, একটি বাল্ক সন্নিবেশ তৈরি করা হবে।


30
আসলে রেকর্ডগুলি সংরক্ষণ করতে আপনার s.commit ()ও দরকার (এটি নির্ধারণ করতে আমার কিছুটা সময় লাগল)।
horcle_buzz

3
আমি স্ক্ল্যাচেমি 1.0.11 দিয়ে এটি চেষ্টা করেছি এবং এটি এখনও 3 টি সন্নিবেশ বিবৃতি দেয়। তবে এটি স্বাভাবিক orm অপারেশনগুলির তুলনায় অনেক দ্রুত।
zidarsk8

3
ওপিএস প্রশ্নের সাথে প্রাসঙ্গিক না হলেও, এটি ওআরএমের কয়েকটি বৈশিষ্ট্য ভঙ্গ করে তা উল্লেখযোগ্য। ডকস.সক্লালচেমি.আর.এইন
ফ্রেইল_আর_আর

@ উদ্যানগেল হ্যাঁ এই পোস্ট করার জন্য আপনাকে ধন্যবাদ। যদিও ওপির শিরোনামটি "বাল্ক লোডিং" নিয়ে উদ্বেগ প্রকাশ করেছে মাল্টি-রেকর্ড সন্নিবেশ বিবৃতি সম্পর্কে তাঁর প্রশ্নের স্ক্ল্যাচেমির বাল্ক লোডিং বৈশিষ্ট্যের সাথে কোনও সম্পর্ক নেই।
W4t3randWind

\copyসিএসভিএল (একই ক্লায়েন্ট থেকে একই সার্ভারে) এর সাথে সিএসভি থেকে একই ডেটা সন্নিবেশ করার তুলনায় আমি সার্ভারের পারফরম্যান্সে একটি বিশাল পার্থক্য দেখতে পাচ্ছি যার ফলস্বরূপ প্রায় 10x আরও সন্নিবেশ / গুলি হয়। স্পষ্টতই এসকিউএলএলচেমির মাধ্যমে এসকিউএল ব্যবহার করার চেয়ে ক্লায়েন্ট-টু-সার্ভারের সাথে যোগাযোগের ক্ষেত্রে একটি প্যাকিং ব্যবহার করে \copy(বা COPYসার্ভারে) বাল্ক-লোডিং হচ্ছে । আরো তথ্য: সন্নিবেশ কর্মক্ষমতা পার্থক্য পোস্টগ্রি বনাম ... লার্জ বাল্ক
gertvdijk

42

Sqlalchemy ডক্স একটি আছে কাজের মধ্যে থাকবেন বিভিন্ন কৌশল যে বাল্ক টিপে ব্যবহার করা যেতে পারে কর্মক্ষমতা করুন:

ওআরএমগুলি মূলত উচ্চ-পারফরম্যান্স বাল্ক সন্নিবেশগুলির জন্য নয় - এটিই পুরো কারণ যা এসকিউএলএলচেমি প্রথম শ্রেণীর উপাদান হিসাবে ওআরএম ছাড়াও কোর সরবরাহ করে।

দ্রুত বल्क সন্নিবেশগুলির ব্যবহারের ক্ষেত্রে, ওআরএম উপরে যে এসকিউএল জেনারেশন এবং এক্সিকিউশন সিস্টেম তৈরি করে তা হ'ল মূল অংশ। এই সিস্টেমটি সরাসরি ব্যবহার করে আমরা এমন একটি INSERT উত্পাদন করতে পারি যা সরাসরি কাঁচা ডাটাবেস এপিআই ব্যবহারের সাথে প্রতিযোগিতামূলক is

বিকল্পভাবে, এসকিউএএচএলএলকেমি ওআরএম বাল্ক অপারেশনস পদ্ধতির পদ্ধতি সরবরাহ করে, যা কোরের স্তরের INSERT এবং আপডেট আপডেটের স্বল্প মাত্রায় ওআরএম-ভিত্তিক অটোমেশন সহ নির্গমন করার জন্য কাজের প্রক্রিয়াটির ইউনিটের সাবসেকশনগুলিতে হুক সরবরাহ করে।

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

classics-MacBook-Pro:sqlalchemy classic$ python test.py
SQLAlchemy ORM: Total time for 100000 records 12.0471920967 secs
SQLAlchemy ORM pk given: Total time for 100000 records 7.06283402443 secs
SQLAlchemy ORM bulk_save_objects(): Total time for 100000 records 0.856323003769 secs
SQLAlchemy Core: Total time for 100000 records 0.485800027847 secs
sqlite3: Total time for 100000 records 0.487842082977 sec

লিপি:

import time
import sqlite3

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,  create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

Base = declarative_base()
DBSession = scoped_session(sessionmaker())
engine = None


class Customer(Base):
    __tablename__ = "customer"
    id = Column(Integer, primary_key=True)
    name = Column(String(255))


def init_sqlalchemy(dbname='sqlite:///sqlalchemy.db'):
    global engine
    engine = create_engine(dbname, echo=False)
    DBSession.remove()
    DBSession.configure(bind=engine, autoflush=False, expire_on_commit=False)
    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)


def test_sqlalchemy_orm(n=100000):
    init_sqlalchemy()
    t0 = time.time()
    for i in xrange(n):
        customer = Customer()
        customer.name = 'NAME ' + str(i)
        DBSession.add(customer)
        if i % 1000 == 0:
            DBSession.flush()
    DBSession.commit()
    print(
        "SQLAlchemy ORM: Total time for " + str(n) +
        " records " + str(time.time() - t0) + " secs")


def test_sqlalchemy_orm_pk_given(n=100000):
    init_sqlalchemy()
    t0 = time.time()
    for i in xrange(n):
        customer = Customer(id=i+1, name="NAME " + str(i))
        DBSession.add(customer)
        if i % 1000 == 0:
            DBSession.flush()
    DBSession.commit()
    print(
        "SQLAlchemy ORM pk given: Total time for " + str(n) +
        " records " + str(time.time() - t0) + " secs")


def test_sqlalchemy_orm_bulk_insert(n=100000):
    init_sqlalchemy()
    t0 = time.time()
    n1 = n
    while n1 > 0:
        n1 = n1 - 10000
        DBSession.bulk_insert_mappings(
            Customer,
            [
                dict(name="NAME " + str(i))
                for i in xrange(min(10000, n1))
            ]
        )
    DBSession.commit()
    print(
        "SQLAlchemy ORM bulk_save_objects(): Total time for " + str(n) +
        " records " + str(time.time() - t0) + " secs")


def test_sqlalchemy_core(n=100000):
    init_sqlalchemy()
    t0 = time.time()
    engine.execute(
        Customer.__table__.insert(),
        [{"name": 'NAME ' + str(i)} for i in xrange(n)]
    )
    print(
        "SQLAlchemy Core: Total time for " + str(n) +
        " records " + str(time.time() - t0) + " secs")


def init_sqlite3(dbname):
    conn = sqlite3.connect(dbname)
    c = conn.cursor()
    c.execute("DROP TABLE IF EXISTS customer")
    c.execute(
        "CREATE TABLE customer (id INTEGER NOT NULL, "
        "name VARCHAR(255), PRIMARY KEY(id))")
    conn.commit()
    return conn


def test_sqlite3(n=100000, dbname='sqlite3.db'):
    conn = init_sqlite3(dbname)
    c = conn.cursor()
    t0 = time.time()
    for i in xrange(n):
        row = ('NAME ' + str(i),)
        c.execute("INSERT INTO customer (name) VALUES (?)", row)
    conn.commit()
    print(
        "sqlite3: Total time for " + str(n) +
        " records " + str(time.time() - t0) + " sec")

if __name__ == '__main__':
    test_sqlalchemy_orm(100000)
    test_sqlalchemy_orm_pk_given(100000)
    test_sqlalchemy_orm_bulk_insert(100000)
    test_sqlalchemy_core(100000)
    test_sqlite3(100000)

1
ধন্যবাদ. সত্যই সহায়ক এবং পুরোপুরি।
স্টিভ বি।

আমি বাইন্ডপ্যারাম ব্যবহার করে আরও একটি উদাহরণ দেখেছি। সিনট্যাক্সটি সুসংগত দেখাচ্ছে, এটি কোনও ভাল?
জে

35

আমি যতদূর জানি, বাল্ক সন্নিবেশ জারি করার জন্য ওআরএম পাওয়ার কোনও উপায় নেই। আমি বিশ্বাস করি যে এর অন্তর্নিহিত কারণটি হচ্ছে এসকিউএলএলচেমিকে প্রতিটি বস্তুর পরিচয় (যেমন, নতুন প্রাথমিক কী) ট্র্যাক করা দরকার এবং বাল্ক সন্নিবেশগুলি এতে হস্তক্ষেপ করে। উদাহরণস্বরূপ, ধরে নেওয়া আপনার fooটেবিলে একটি idকলাম রয়েছে এবং এটি একটি Fooশ্রেণিতে ম্যাপ করা হয়েছে :

x = Foo(bar=1)
print x.id
# None
session.add(x)
session.flush()
# BEGIN
# INSERT INTO foo (bar) VALUES(1)
# COMMIT
print x.id
# 1

যেহেতু এসকিউএলএলচেমি x.idঅন্য কোনও জিজ্ঞাসা জারি না করে এর জন্য মানটি তুলেছে , তাই আমরা অনুমান করতে পারি যে এটি সরাসরি INSERTবিবৃতি থেকে পেয়েছে । যদি আপনার একই উদাহরণগুলির মাধ্যমে তৈরি অবজেক্টগুলিতে পরবর্তী অ্যাক্সেসের প্রয়োজন না হয় তবে আপনি নিজের প্রবেশের জন্য ওআরএম স্তরটি এড়িয়ে যেতে পারেন:

Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}])
# INSERT INTO foo (bar) VALUES ((1,), (2,), (3,))

এসকিউএলএলচেমি যে কোনও বিদ্যমান বস্তুর সাথে এই নতুন সারিগুলি মেলে না, তাই পরবর্তী কোনও ক্রিয়াকলাপের জন্য আপনাকে তাদের নতুন করে জিজ্ঞাসা করতে হবে।

যতক্ষণ না বাসি ডেটা সম্পর্কিত, এটি মনে রাখা সহায়ক যে সেশনটির বাইরে ডাটাবেস কখন পরিবর্তন করা হয় তা সেশনের কোনও অন্তর্নিহিত উপায় নেই। বিদ্যমান দৃষ্টান্তগুলির মাধ্যমে বাহ্যিকভাবে পরিবর্তিত ডেটা অ্যাক্সেস করার জন্য, দৃষ্টান্তগুলি অবশ্যই মেয়াদোত্তীর্ণ হিসাবে চিহ্নিত করতে হবে । এটি ডিফল্টরূপে ঘটে session.commit(), তবে কল করে session.expire_all()বা দ্বারা নিজেই করা যেতে পারে session.expire(instance)। একটি উদাহরণ (এসকিউএল বাদ দেওয়া):

x = Foo(bar=1)
session.add(x)
session.commit()
print x.bar
# 1
foo.update().execute(bar=42)
print x.bar
# 1
session.expire(x)
print x.bar
# 42

session.commit()মেয়াদ শেষ হয়ে যায় x, তাই প্রথম মুদ্রণ বিবৃতি সুস্পষ্টভাবে একটি নতুন লেনদেন এবং পুনরায় অনুসন্ধানের xবৈশিষ্ট্যগুলি খোলে । যদি আপনি প্রথম মুদ্রণ বিবৃতিটি মন্তব্য করেন তবে আপনি লক্ষ্য করবেন যে দ্বিতীয়টি এখন সঠিক মানটি তুলবে, কারণ আপডেটের পরে নতুন ক্যোয়ারী নির্গত হয় না।

এটি লেনদেনের বিচ্ছিন্নতার দৃষ্টিকোণ থেকে বোঝা যায় - আপনার কেবল লেনদেনের মধ্যে বাহ্যিক পরিবর্তনগুলি বেছে নেওয়া উচিত। যদি এটি আপনার সমস্যার কারণ হয়ে থাকে তবে আমি আপনার অ্যাপ্লিকেশনটির লেনদেনের সীমানাটি তাত্ক্ষণিকভাবে পৌঁছানোর পরিবর্তে স্পষ্ট করার বা পুনরায় চিন্তা করার পরামর্শ দিচ্ছি session.expire_all()


আপনার জবাবের জন্য ধন্যবাদ, আমি একটি যেতে যাচ্ছি। মেয়াদউত্তীর্ণ ইস্যু ডাব্লুআরটি, আমি যা দেখলাম তা এক রকম নয়। আমি টার্বোগার্সে একটি স্কোপড সেশন ব্যবহার করছি। একটি গেটসেশন ()। কোয়েরি (ফু) .ফিল্টার .... সমস্ত () অনুরোধের উপর নির্ভর করে বিভিন্ন জিনিস ফিরিয়ে দিয়েছে, আমি এটি পুনরায় চালু না করা পর্যন্ত ডিবিতে থাকা আপডেট হওয়া রেকর্ডগুলি ফিরিয়ে দেয়নি। আমি একটি অটোকমিট = সত্য করে এবং এমন কোনও কিছু যুক্ত করে এই সমস্যাটি সমাধান করেছি request অনুরোধটি শেষ হওয়ার পরে সেশনটি সরিয়ে () d (আমি জড়ো করেছি আপনাকে যেভাবেই করা উচিত)।
নিক হোল্ডেন

আমার ধারণা এটি অনুরোধের উপর নির্ভর করে বিভিন্ন জিনিস ফিরিয়ে দিয়েছে কারণ এতে পুলের প্রতিটি থ্রেড প্রতি স্কোপড সেশন ছিল এবং সেশনগুলি বিভিন্ন রাজ্যে ছিল? এটি কিছুটা অদ্ভুত বলে মনে হয়েছিল যে সদ্য নতুন অনুরোধের পরে নতুন ডেটা পাবেন না। আমি প্রত্যাশা করি অটোকোমিট = মিথ্যা কী করছে তা আমি ভুল বুঝতে পেরেছি
নিক হোল্ডেন

এর সাথে autocommit=False, আমি বিশ্বাস করি আপনাকে session.commit()অনুরোধটি সম্পূর্ণ করার আহ্বান জানানো উচিত (আমি টার্বো জিয়ার সাথে পরিচিত নই, তাই যদি ফ্রেমওয়ার্ক স্তরে এটি আপনার জন্য পরিচালিত হয় তবে এটিকে এড়িয়ে যান)। আপনার পরিবর্তনগুলি এটি ডেটাবেজে পরিণত হয়েছে তা নিশ্চিত করার পাশাপাশি, এটি সেশনের সমস্ত কিছুর মেয়াদ শেষ করবে। সেই সেশনের পরবর্তী ব্যবহার না হওয়া পর্যন্ত পরবর্তী লেনদেন শুরু হবে না, সুতরাং একই থ্রেডে ভবিষ্যতের অনুরোধগুলি বাসি ডেটা দেখতে পাবে না।
dhaffey

10
বিকল্প শৈলী:session.execute(Foo.__table__.insert(), values)
জোরিল

6
নোট করুন যে স্ক্ল্যাচচেমির নতুন সংস্করণগুলিতে বাল্ক সন্নিবেশ ক্ষমতা রয়েছে: ডকস.সক্ল্যাচেমি.আর.এইন
ওয়েন ওয়ার্নার

18

আমি সাধারণত এটি ব্যবহার করে করি add_all

from app import session
from models import User

objects = [User(name="u1"), User(name="u2"), User(name="u3")]
session.add_all(objects)
session.commit()

2
আপনি কি নিশ্চিত যে এটি কাজ করে? এটি কেবল .addএকবারে তাদেরকে অধিবেশন করার সমতুল্য করে না ?
আলেক

এটি পদ্ধতির নাম অনুসারে স্বজ্ঞাত হতে পারে, ডক্সটি বিশদে যায় না: Add the given collection of instances to this Session.এটি কোনও পরিমাণে সন্নিবেশ করে না বলে বিশ্বাস করার কোনও যুক্তি আছে কি?
রিউবানো

3
আমি মনে করি না এটি খুব পাল্টে দেওয়া - এটি আসলে আপনি যা জিজ্ঞাসা করেন সেগুলি সমস্তই যুক্ত করে। অধিবেশনটিতে সমস্ত জিনিস যুক্ত করার কোনও কিছুই মনে হয় না এটি এর অন্তর্নিহিত এসকিউএল বিবৃতি জারি করার ইঙ্গিত দেয়। উত্সটির দিকে তাকানো : github.com/zzzeek/sqlalchemy/blob/… এটিকে বাস্তবে কেবল প্রতিটি আইটেম স্বতন্ত্র বলে মনে হয় । .add
আলেক

এটা ভাল তুলনায় কাজ করে, bulk_save_objects()একটি সঙ্গে flush(), আমরা বস্তুর আইডি পেতে পারেন, কিন্তু bulk_save_objects()পারে না (সঙ্গে ঘটনা flush()বলা হয়)।
coanor

14

0.8 সংস্করণ হিসাবে এসকিউএএলএলচেমিতে সরাসরি সমর্থন যুক্ত করা হয়েছিল

অনুযায়ী ডক্স , connection.execute(table.insert().values(data))কৌতুক করতে হবে। (দ্রষ্টব্য যে এটি একই নয়connection.execute(table.insert(), data) যার ফলস্বরূপ কলের মাধ্যমে অনেকগুলি পৃথক সারি সন্নিবেশ করানো হয় executemany)। স্থানীয় সংযোগ ছাড়া অন্য কোনও ক্ষেত্রে পারফরম্যান্সের পার্থক্য প্রচুর হতে পারে।


10

এসকিউএলএলচেমি সংস্করণে এটি চালু করেছিল 1.0.0:

বাল্ক অপারেশন - এসকিউএএলএলএকমি ডক্স

এই অপারেশনগুলির সাহায্যে আপনি এখন বাল্ক সন্নিবেশ বা আপডেটগুলি করতে পারেন!

উদাহরণস্বরূপ (যদি আপনি সাধারণ টেবিল INSERTs এর জন্য সর্বনিম্ন ওভারহেড চান), আপনি ব্যবহার করতে পারেন Session.bulk_insert_mappings():

loadme = [(1, 'a'),
          (2, 'b'),
          (3, 'c')]
dicts = [dict(bar=t[0], fly=t[1]) for t in loadme]

s = Session()
s.bulk_insert_mappings(Foo, dicts)
s.commit()

অথবা, আপনি চাইলে, loadmeটিউপসগুলি এড়িয়ে যান এবং সরাসরি অভিধানগুলি লিখুন dicts(তবে আমি সমস্ত শব্দগুচ্ছতা ডেটা ছেড়ে রেখে লুপে অভিধানের একটি তালিকা লোড করা সহজ মনে করি)।


7

পাইয়ের উত্তরটি সঠিক তবে একটি বিষয় হ'ল bulk_save_objectsডিফল্টরূপে অবজেক্টগুলির প্রাথমিক কীগুলি ফিরিয়ে দেয় না, যদি এটি আপনার উদ্বেগের বিষয় হয়। সেট return_defaultsকরুনTrue এই আচরণ জন্য।

ডকুমেন্টেশন এখানে

foos = [Foo(bar='a',), Foo(bar='b'), Foo(bar='c')]
session.bulk_save_objects(foos, return_defaults=True)
for foo in foos:
    assert foo.id is not None
session.commit()

2
পতাকা সহ একটি সতর্কতা অবলম্বন করা আবশ্যক। এটি ক্রমান্বয়ে এক সময় একটি বস্তু sertোকাবে এবং উল্লেখযোগ্য পারফরম্যান্স লাভ সেখানে নাও হতে পারে [1]। আমার ক্ষেত্রে, কর্মক্ষমতা হ্রাস পেয়েছে যা ওভারহেডের কারণে আমার সন্দেহ হয়েছিল। [1]: ডকস.সক্ল্যাচেমি.আর.আর্গ
এএন

6

সমস্ত রাস্তাগুলি রোমে নিয়ে যায় , তবে তাদের মধ্যে কয়েকটি পাহাড় অতিক্রম করে, ফেরিগুলির প্রয়োজন হয় তবে আপনি যদি দ্রুত সেখানে যেতে চান তবে কেবল মোটরওয়েটি নিয়ে যান।


এক্ষেত্রে মোটরওয়েতে সাইকোপজি 2 এর এক্সিকিউট_ব্যাচ () বৈশিষ্ট্যটি ব্যবহার করতে হবে । ডকুমেন্টেশন এটি সেরা বলে:

এর বর্তমান বাস্তবায়ন executemany()(একটি অত্যন্ত দাতব্য সংক্ষিপ্ত বিবরণ ব্যবহার করে) বিশেষভাবে সম্পাদন করছে না। এই ফাংশনগুলি পরামিতিগুলির একটি সেট বিরুদ্ধে একটি বিবৃতি পুনরাবৃত্তি কার্যকর করতে ব্যবহার করা যেতে পারে। সার্ভারের রাউন্ডট্রিপসের সংখ্যা হ্রাস করে পারফরম্যান্স ব্যবহারের চেয়ে প্রশস্ততার অর্ডার হতে পারে executemany()

আমার নিজের পরীক্ষা execute_batch()হয় প্রায় দ্বিগুণ হিসাবে দ্রুত হিসাবেexecutemany() , এবং আরো টোয়েকিং জন্য PAGE_SIZE কনফিগার করতে বিকল্প দেয় (যদি আপনি চালক থেকে বের কর্মক্ষমতা গত 2-3% আলিঙ্গন করতে চান)।

use_batch_mode=Trueআপনি ইঞ্জিনটি ইনস্ট্যান্ট করার সাথে সাথে প্যারামিটার হিসাবে সেট করে যদি এসকিএএলএলচেমি ব্যবহার করেন তবে একই বৈশিষ্ট্যটি সহজেই সক্ষম করা যায়create_engine()


নোট: psycopg2 এর execute_valuesহয় দ্রুত psycopg2 এর চেয়ে execute_batchযখন বাল্ক টিপে করছেন!
এফিয়ার

5

এটি একটি উপায়:

values = [1, 2, 3]
Foo.__table__.insert().execute([{'bar': x} for x in values])

এটি এর মতো সন্নিবেশ করানো হবে:

INSERT INTO `foo` (`bar`) VALUES (1), (2), (3)

রেফারেন্স: দ্য SQLAlchemy প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী বিভিন্ন পদ্ধতি কমিট জন্য benchmarks অন্তর্ভুক্ত করা হয়েছে।


3

আমি এখনও অবধি সবচেয়ে ভাল উত্তরটি স্কেলচেমি ডকুমেন্টেশনে পেয়েছি:

http://docs.sqlalchemy.org/en/latest/faq/performance.html#im-inserting-400-000-rows-with-the-orm-and-it-s-really-slow

সম্ভাব্য সমাধানগুলির একটি মানদণ্ডের একটি সম্পূর্ণ উদাহরণ রয়েছে।

ডকুমেন্টেশন হিসাবে প্রদর্শিত:

বাল্ক_সেভ_বজেক্টগুলি সেরা সমাধান নয় তবে এটি সম্পাদন সঠিক performance

পাঠযোগ্যতার দিক থেকে দ্বিতীয় সেরা বাস্তবায়ন আমার মনে হয় এসকিউএএলএলচেমি কোরের সাথে ছিল:

def test_sqlalchemy_core(n=100000):
    init_sqlalchemy()
    t0 = time.time()
    engine.execute(
        Customer.__table__.insert(),
            [{"name": 'NAME ' + str(i)} for i in xrange(n)]
    )

এই ফাংশনটির প্রসঙ্গটি ডকুমেন্টেশন নিবন্ধে দেওয়া হয়েছে।

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