পাইথন এসকিউএল কোয়েরি স্ট্রিং ফর্ম্যাটিং


102

আমি একটি এসকিউএল ক্যোয়ারী স্ট্রিং ফর্ম্যাট করার সর্বোত্তম উপায় সন্ধান করার চেষ্টা করছি। আমি যখন আমার অ্যাপ্লিকেশনটি ডিবাগ করছি তখন আমি সমস্ত স্ক্যুয়েল ক্যোয়ারী স্ট্রিং ফাইল করতে লগ করতে চাই এবং এটি গুরুত্বপূর্ণ যে স্ট্রিংটি সঠিকভাবে ফর্ম্যাট করা হয়েছে।

বিকল্প 1

def myquery():
    sql = "select field1, field2, field3, field4 from table where condition1=1 and condition2=2"
    con = mymodule.get_connection()
    ...
  • এটি স্কয়ার স্ট্রিং প্রিন্ট করার জন্য ভাল।
  • স্ট্রিংটি দীর্ঘ এবং 80 টি অক্ষরের মানক প্রস্থের সাথে মানানসই না হলে এটি কোনও ভাল সমাধান নয়।

বিকল্প 2

def query():
    sql = """
        select field1, field2, field3, field4
        from table
        where condition1=1
        and condition2=2"""
    con = mymodule.get_connection()
    ...
  • এখানে কোডটি স্পষ্ট তবে আপনি যখন স্কয়ার কোয়েরি স্ট্রিংটি মুদ্রণ করবেন তখন আপনি এই সমস্ত বিরক্তিকর সাদা স্পেস পেয়ে যাবেন।

    আপনি 'field n ক্ষেত্র 1, ফিল্ড 2, ফিল্ড 3, ফিল্ড 4 field n_ _ ___ টেবিল থেকে \ n _ ___ যেখানে শর্ত 1 = 1 \ n _ ___ _ এবং শর্ত 2 = 2' নির্বাচন করুন

দ্রষ্টব্য: আমি সাদা স্পেসগুলি আন্ডারস্কোর দিয়ে প্রতিস্থাপন করেছি _, কারণ তারা সম্পাদক দ্বারা ছাঁটা হয়েছে

বিকল্প 3

def query():
    sql = """select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
    con = mymodule.get_connection()
    ...
  • আমি এই বিকল্পটি পছন্দ করি না কারণ এটি ভাল ট্যাবুলেটেড কোডটির স্বচ্ছতা ভঙ্গ করে।

বিকল্প 4

def query():
    sql = "select field1, field2, field3, field4 " \
          "from table " \
          "where condition1=1 " \
          "and condition2=2 "
    con = mymodule.get_connection()    
    ...
  • আমি এই বিকল্পটি পছন্দ করি না কারণ প্রতিটি লাইনে সমস্ত অতিরিক্ত টাইপ করা এবং কোয়েরিটি সম্পাদনা করাও কঠিন।

আমার জন্য সর্বোত্তম সমাধানটি বিকল্প 2 হবে তবে আমি যখন এসকিএল স্ট্রিংটি প্রিন্ট করি তখন অতিরিক্ত হোয়াইটস্পেসগুলি আমি পছন্দ করি না।

আপনি অন্য কোন বিকল্প জানেন?


সাইকাপগের লোকেরা এটিকেই কোয়েরি স্ট্রিংগুলির রচনার জন্য aïïï approach approach approach approach।। Approach approach approach approach approach approach call call call call call call call call call call call call call call call call call call call call call call call call call string string string string init string init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init init।।।।।।। Init init init init init init init init । পরিবর্তে এসকিউএল ইনজেকশন আক্রমণগুলি এড়াতে এবং এসকিউএল আক্ষরিক থেকে পাইথন অবজেক্টগুলিকে স্বয়ংক্রিয়ভাবে রূপান্তর করতে কোয়েরি প্যারামিটার ব্যবহার করুন। stackoverflow.com/questions/3134691/…
ম্যাথু কর্নেল

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

উত্তর:


136

এত পুরানো থ্রেডে পোস্ট করার জন্য দুঃখিত - তবে পাইথোনিক 'বেস্ট' এর প্রতি আবেগ ভাগ করে নেওয়া এমন কেউ হিসাবে আমি ভেবেছিলাম আমি আমাদের সমাধানটি ভাগ করে নিই।

সমাধানটি হ'ল পাইথনের স্ট্রিং লিটারাল কনকাটেনেশন ( http://docs.python.org/ ) ব্যবহার করে এসকিউএল স্টেটমেন্ট তৈরি করা , যা বিকল্প 2 এবং বিকল্প 4 এর মধ্যে কোথাও যোগ্যতা অর্জন করতে পারে

কোড নমুনা:

sql = ("SELECT field1, field2, field3, field4 "
       "FROM table "
       "WHERE condition1=1 "
       "AND condition2=2;")

এফ-স্ট্রিংয়ের পাশাপাশি কাজ করে :

fields = "field1, field2, field3, field4"
table = "table"
conditions = "condition1=1 AND condition2=2"

sql = (f"SELECT {fields} "
       f"FROM {table} "
       f"WHERE {conditions};")

পেশাদাররা:

  1. এটি পাইথোনিক 'ভাল ট্যাবুলেটেড' ফর্ম্যাটটি ধরে রাখে, তবে বহিরাগত স্থানের অক্ষরগুলি যোগ করে না (যা লগিংকে দূষিত করে)।
  2. এটি বিকল্প 4 এর ব্যাকস্ল্যাশ ধারাবাহিকতা কদর্যতা এড়িয়ে চলেছে, যা বিবৃতি যোগ করা (সাদা-স্পেস অন্ধত্বের কথা উল্লেখ না করা) কঠিন করে তোলে।
  3. এবং আরও, ভিআইএম-তে বিবৃতিটি প্রসারিত করা খুব সহজ (কেবলমাত্র কার্সারটিকে সন্নিবেশ বিন্দুতে সজ্জিত করুন এবং একটি নতুন লাইন খোলার জন্য SHIFT-O টিপুন )।

4
এটি যদি মুদ্রণের জন্য হয় তবে আমার মনে হয় এর চেয়ে ভাল বিকল্পটি এটির সাথে মিউটিলাইন স্ট্রিং হিসাবে লেখা """এবং textwrap.dedent()আউটপুট দেওয়ার আগে ব্যবহার করা উচিত
slezica

আমি সেই বিকল্পটি দিয়ে খেলি, তবে এটি লগ আউটপুটটিও বহুগুণে তৈরি করে। একটি ডিবি চ্যাটি অ্যাপ্লিকেশন ট্র্যাক করার সময়, এর ফলে ভলিউম আউটপুট হয়।
ব্যবহারকারী590028

4
এটি একটি পুরানো থ্রেড, তবে আমি এই ফর্ম্যাটটিকে একটি সেরা অনুশীলন হিসাবে ব্যবহার করছি, তবে এটি দীর্ঘতর প্রশ্নের সাথে ক্লান্তিকর হয়ে
ওঠে

8
"sql query"এসকিউএল স্ট্রিংগুলি (যা মান হিসাবে একক উদ্ধৃতি ব্যবহার করে) এর সাথে ঝামেলা এড়ানোর জন্য আমাদের কি সর্বদা ডাবল কোট ব্যবহার করা উচিত নয় ?
tpvasconcelos 22'19

19

আপনি স্পষ্টতই এসকিউএল লেখার প্রচুর উপায় বিবেচনা করেছেন যাতে এটি ঠিক আছে, তবে আপনার এসকিউএল আপনার পছন্দ নয় এমনভাবে লেখার চেয়ে আপনি কীভাবে 'প্রিন্ট' বিবৃতিটি ডিবাগ লগিংয়ের জন্য ব্যবহার করেন? উপরে আপনার পছন্দসই বিকল্পটি ব্যবহার করে, লগিং ফাংশন সম্পর্কিত কীভাবে এটি:

def debugLogSQL(sql):
     print ' '.join([line.strip() for line in sql.splitlines()]).strip()

sql = """
    select field1, field2, field3, field4
    from table"""
if debug:
    debugLogSQL(sql)

লাইনটি যদি আপনার পছন্দসই দৈর্ঘ্যের চেয়ে দীর্ঘ হয় তবে একাধিক লাইনে লগ করা স্ট্রিংকে বিভক্ত করতে অতিরিক্ত যুক্তি যুক্ত করাও এটি তুচ্ছ করে তোলে।


11

সবচেয়ে পরিষ্কার উপায়টি আমি স্ক্যাল স্টাইল গাইড দ্বারা অনুপ্রাণিত ।

sql = """
    SELECT field1, field2, field3, field4
      FROM table
     WHERE condition1 = 1
       AND condition2 = 2;
"""

মূলত, একটি ধারা শুরু হওয়া কীওয়ার্ডগুলি ডান-প্রান্তিক হওয়া উচিত এবং ক্ষেত্রের নাম ইত্যাদি, বামে প্রান্তিক করা উচিত। এটি দেখতে খুব ঝরঝরে এবং ডিবাগ করাও সহজ।


2
sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1={} "
       "and condition2={}").format(1, 2)

Output: 'select field1, field2, field3, field4 from table 
         where condition1=1 and condition2=2'

যদি শর্তের মান একটি স্ট্রিং হওয়া উচিত তবে আপনি এটি করতে পারেন:

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1='{0}' "
       "and condition2='{1}'").format('2016-10-12', '2017-10-12')

Output: "select field1, field2, field3, field4 from table where
         condition1='2016-10-12' and condition2='2017-10-12'"

4
কখনও কখনও এটি করবেন না দয়া করে। এটিকে এসকিউএল ইঞ্জেকশন বলা হয় এবং এটি সত্যই বিপজ্জনক। খুব সুন্দর প্রতিটি পাইথন ডাটাবেস লাইব্রেরি পরামিতি ব্যবহারের জন্য একটি সুবিধা সরবরাহ করে। আপনি যদি format()এসকিউএল স্ট্রিংগুলি ব্যবহার করে নিজেকে ধরেন তবে এটি একটি প্রধান কোডের গন্ধ।
mattmc3

আমি মনে করি না আমরা এটি ব্যবহার করতে পারি না, এটি ব্যবহারের আগে আপনাকে প্যারামিটারগুলি যাচাই করতে হবে এবং আপনি কী পাস করবেন তা আপনার জানা উচিত।
পাইংপাং

where condition1=:field1মানকে প্যারামিটার হিসাবে ব্যবহার করা এবং তারপরে মানগুলি পাস করার চেয়ে বৈধতা অনেক বেশি ত্রুটিযুক্ত । আপনি যদি ব্যবহার করেন তবে আপনার এসকিউএল-তে .format()একটি পপ করার উপায় হতে পারে ';DROP TABLE Users। প্যারামিটারগুলি কীভাবে সঠিকভাবে ব্যবহার করতে হয় তার জন্য PEP-249 দেখুন। python.org/dev/peps/pep-0249/#paramstyle
mattmc3

1

আপনি inspect.cleandocআপনার মুদ্রিত এসকিউএল স্টেটমেন্টটি সুন্দরভাবে ফর্ম্যাট করতে ব্যবহার করতে পারেন ।

এটি আপনার বিকল্প 2 দিয়ে খুব ভাল কাজ করে ।

দ্রষ্টব্য: print("-"*40)যদি আপনি ক্ল্যান্ডক ব্যবহার না করেন তবে কেবলমাত্র অতিমাত্রায় ফাঁকা লাইনগুলি প্রদর্শন করতে পারেন।

from inspect import cleandoc
def query():
    sql = """
        select field1, field2, field3, field4
        from table
        where condition1=1
        and condition2=2
    """

    print("-"*40)
    print(sql)
    print("-"*40)
    print(cleandoc(sql))
    print("-"*40)

query()

আউটপুট:

----------------------------------------

        select field1, field2, field3, field4
        from table
        where condition1=1
        and condition2=2

----------------------------------------
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2
----------------------------------------

ডক্স থেকে :

ইন্সপেক্ট.ক্লানডোক (ডক)

কোডের ব্লকগুলির সাথে লাইন আপ করার জন্য ডেন্ট্রাস্টিংগুলি থেকে ইন্ডেন্টেশন পরিষ্কার করুন।

সমস্ত নেতৃস্থানীয় সাদা স্থান প্রথম লাইন থেকে সরানো হয়েছে। দ্বিতীয় লাইন থেকে সমানভাবে মুছে ফেলা যায় এমন যে কোনও নেতৃস্থানীয় হোয়াইটস্পেস সরানো হবে। শুরুতে এবং শেষে খালি লাইনগুলি পরে মুছে ফেলা হয়। এছাড়াও, সমস্ত ট্যাবগুলি স্পেসে প্রসারিত করা হয়।


0

এড়ানোর জন্য সম্পূর্ণরূপে বিন্যাস , আমি মনে করি একটি দুর্দান্ত সমাধান ব্যবহার করা পদ্ধতি

কোনও পদ্ধতিতে কলিংয়ের ফলে আপনি এই পদ্ধতিতে যে প্রশ্নটি রাখতে চান তার ফলাফল দেয় gives আপনি আসলে একটি পদ্ধতির মধ্যে একাধিক প্রশ্নের প্রক্রিয়া করতে পারেন । কলটি কেবলমাত্র শেষ কোয়েরিটি কল করেছিল তা ফিরিয়ে দেবে

MYSQL

DROP PROCEDURE IF EXISTS example;
 DELIMITER //
 CREATE PROCEDURE example()
   BEGIN
   SELECT 2+222+2222+222+222+2222+2222 AS this_is_a_really_long_string_test;
   END //
 DELIMITER;

#calling the procedure gives you the result of whatever query you want to put in this procedure. You can actually process multiple queries within a procedure. The call just returns the last query result
 call example;

পাইথন

sql =('call example;')

-1

আপনি ক্ষেত্রের নামগুলি একটি অ্যারে "ক্ষেত্রগুলিতে" রেখে দিতে পারেন এবং তারপরে:


sql = 'select %s from table where condition1=1 and condition2=2' % (
 ', '.join(fields))

যদি আপনার অবস্থার তালিকাটি বাড়তে থাকে তবে আপনি 'এবং' .জয়াইন (শর্তাবলী) ব্যবহার করে একই কাজ করতে পারেন
jcomeau_ictx

আপনার সমাধান সহ, ক্যোয়ারীটি অপশন with এর চেয়ে সম্পাদনা করা আরও বেশি কঠিন এবং এটি পড়তেও সমস্যা হবে।
ssoler

@ এসোলার, এটি কীভাবে কাজ করে তার উপর নির্ভর করে। আমি আমার প্রোগ্রামগুলিতে কয়েকটি ভেরিয়েবল ঘোষণা করি এবং তার পরিবর্তে স্ট্রিংয়ের অ্যারে ব্যবহার করি যা কমপক্ষে আমার দ্বারা উপরের মতো পদ্ধতিগুলিকে খুব দরকারী এবং রক্ষণাবেক্ষণযোগ্য করে তোলে ।
jcomeau_ictx

-1

আমি বিকল্প 2 টি আটকে থাকার পরামর্শ দেব (আমি সবসময় এর চেয়ে জটিলতর প্রশ্নের জন্য সবসময় ব্যবহার করছি SELECT * FROM table) এবং আপনি যদি এটি একটি সুন্দর উপায়ে মুদ্রণ করতে চান তবে আপনি সর্বদা একটি পৃথক মডিউল ব্যবহার করতে পারেন ।


-1

এক বা দুটি লাইনে ফিট করতে পারে এমন ছোট প্রশ্নের জন্য, আমি উপরের শীর্ষে ভোট দেওয়া সমাধানটিতে স্ট্রিং আক্ষরিক সমাধানটি ব্যবহার করি। দীর্ঘ প্রশ্নের জন্য, আমি তাদের .sqlফাইলগুলিতে ছড়িয়ে দেব । আমি তখন ফাইলটি লোড করতে এবং স্ক্রিপ্টটি কার্যকর করতে একটি মোড়ক ফাংশন ব্যবহার করি, এরকম কিছু:

script_cache = {}
def execute_script(cursor,script,*args,**kwargs):
    if not script in script_cache:
        with open(script,'r') as s:
            script_cache[script] = s
    return cursor.execute(script_cache[script],*args,**kwargs)

অবশ্যই এটি প্রায়শই ক্লাসের অভ্যন্তরে থাকে তাই আমাকে সাধারণত cursorপরিষ্কারভাবে পাস করতে হয় না । আমি সাধারণত ব্যবহার করি codecs.open()তবে এটি সাধারণ ধারণা পায়। তারপরে এসকিউএল স্ক্রিপ্টগুলি তাদের নিজস্ব সিনট্যাক্স হাইলাইট করে নিজের ফাইলগুলিতে সম্পূর্ণ স্ব-অন্তর্ভুক্ত।


-2
sql = """\
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2
"""

[মন্তব্য করতে রেসপন্সে সম্পাদনা করুন]
কোনও পদ্ধতির ভিতরে এসকিউএল স্ট্রিং থাকার অর্থ এই নয় যে আপনাকে এটি "ট্যাবলেট" করতে হবে:

>>> class Foo:
...     def fubar(self):
...         sql = """\
... select *
... from frobozz
... where zorkmids > 10
... ;"""
...         print sql
...
>>> Foo().fubar()
select *
from frobozz
where zorkmids > 10
;
>>>

আইএমও এটি অপশন_2 এর মতো
স্লোলার

@ এসোলার: আপনার বিকল্পের সমস্ত লাইনে শীর্ষস্থান রয়েছে ; মনে রাখবেন যে আপনার উদাহরণ আগে নেতৃস্থানীয় স্পেস বাদ দেয় select। আমার উত্তরের নেতৃস্থানীয় স্থান নেই। আপনি কী মতামত তৈরি করতে নেতৃত্ব দেন যে তারা একই রকম?
জন ম্যাচিন

আপনি যদি কোনও পদ্ধতির অভ্যন্তরে আপনার এসকিএল স্ট্রিংটি রাখেন তবে আপনাকে সমস্ত লাইন সারণি করতে হবে (বিকল্প ২)। এর সম্ভাব্য সমাধান হ'ল অপশন 14 _3
ssoler

@ এসোলার: দুঃখিত, আমি এই মন্তব্যটি বুঝতে পারি না। আমার আপডেট করা উত্তর দেখুন দয়া করে।
জন মাচিন

আপনার আপডেট হওয়া উত্তরটি আমার অপশন 2004, তাই না? আমি এই বিকল্পটি পছন্দ করি না কারণ এটি ভাল ট্যাবুলেটেড কোডটির স্বচ্ছতা ভঙ্গ করে।
ssoler
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.