ক্লজ ইন অজগর মাইএসকিউএলডিবিতে ব্যবহারের জন্য একটি তালিকা পেশ করা


86

আমি জানি যে কীভাবে কোনও স্ট্রিংয়ের তালিকায় ম্যাপ করতে হবে:

foostring = ",".join( map(str, list_of_ids) )

এবং আমি জানি যে আমি স্ট্রিংটিকে একটি আইএন শৃঙ্খলে আনার জন্য নিম্নলিখিতটি ব্যবহার করতে পারি:

cursor.execute("DELETE FROM foo.bar WHERE baz IN ('%s')" % (foostring))

আমার যা প্রয়োজন তা হ'ল মাইএসকিউএলডিবি ব্যবহার করে একই জিনিসটি নিরাপদে (এসকিউএল ইঞ্জেকশন এড়ানো) সম্পাদন করা। উপরোক্ত উদাহরণে কারণ foostring কার্যকর করার আর্গুমেন্ট হিসাবে পাস করা হয় নি, এটি ঝুঁকিপূর্ণ। আমার কাছে মাইএসকিএল লাইব্রেরির বাইরেও উদ্ধৃতি দিতে হবে এবং পালাতে হবে।

(এখানে একটি সম্পর্কিত এসও প্রশ্ন রয়েছে , তবে সেখানে তালিকাভুক্ত উত্তরগুলি মাইএসকিউএলডিবির পক্ষে কাজ করে না বা এসকিউএল ইঞ্জেকশনের জন্য ঝুঁকির মধ্যে রয়েছে।)


আপনি যদি অনুরূপ প্রশ্ন পিএইচপি মধ্যে সম্পন্ন করা হয় থেকে কিছু অনুপ্রেরণা পেতে সক্ষম হতে পারে stackoverflow.com/questions/327274/...
Zoredache


@ এমএলইউবুকে কোয়েরিতে একাধিক তালিকা পাস করার বিষয়ে কোনও ধারণা?
দীপেন দেদানিয়া

উত্তর:


161

list_of_idsসরাসরি ব্যবহার করুন :

format_strings = ','.join(['%s'] * len(list_of_ids))
cursor.execute("DELETE FROM foo.bar WHERE baz IN (%s)" % format_strings,
                tuple(list_of_ids))

এইভাবে আপনি নিজেকে উদ্ধৃত করা এড়িয়ে চলুন এবং সমস্ত ধরণের স্কালো ইনজেকশন এড়িয়ে চলুন।

নোট করুন যে ডেটা ( list_of_ids) সরাসরি মাইএসকিএল এর ড্রাইভারের কাছে প্যারামিটার হিসাবে চলেছে (ক্যোয়ারী পাঠ্যে নয়) সুতরাং কোনও ইঞ্জেকশন নেই। আপনি স্ট্রিংয়ে যে কোনও অক্ষর চান তা ছেড়ে দিতে পারেন, অক্ষর মুছে ফেলার বা উদ্ধৃতি দেওয়ার দরকার নেই।


4
@ হাইকোগার্লাচ: আমি% s এর উদ্ধৃতি দিচ্ছি না ... প্রথম লাইনটি "% s,% s,% s" এর স্ট্রিং তৈরি করে ... তালিকা_অফ_আইডি দৈর্ঘ্যের একই আকার।
nosklo

আরগ, আপনি ঠিক বলেছেন। আরও শক্ত দেখা দরকার। একরকম আমি এটি মিশ্রিত। যদিও ভাল সমাধান।

স্ক্লাইটেও কি এই কাজ করবে? কারণ আমি কেবল এটি চেষ্টা করেছি এবং মনে হচ্ছে সিনট্যাক্স ত্রুটিগুলি নির্দেশ করে।
সোহাইব

@ সোহাইব স্ক্লাইটে প্রতিস্থাপনের চরটি ?নয় %sতাই যদি আপনি প্রথম লাইনটি পরিবর্তন করেন তবে এটি কাজ করবে format_strings = ','.join('?' * len(list_of_ids))
nosklo

4
@ কেডাস আপনার ক্ষেত্রে আপনি চান না যে % format_stringsঅংশটি %sআপনার ক্যোয়ারীতে অন্য স্থানধারককে পরিবর্তন করবে , কেবল IN (%s)স্থানধারক - এটি অর্জনের %query = ("select distinct cln from vcf_commits where branch like %%s and repository like %%s and filename in (%s) and author not like %%s" % format_strings,); cursor.execute(query, (branch, repository) + tuple(fname_list) + (invalid_author,))
উপায়টি

6

যদিও এই প্রশ্নটি বেশ পুরানো, ভেবেছিলাম যে অন্য কেউ আমার কী চাইছে সে ক্ষেত্রে প্রতিক্রিয়া জানানো ভাল

যখন আমাদের অনেকগুলি প্যারাম থাকে বা আমরা নামী পরামিতি ব্যবহার করতে চাইলে গৃহীত উত্তর অগোছালো হয়ে যায়

কিছু পরীক্ষার পরে

ids = [5, 3, ...]  # list of ids
cursor.execute('''
SELECT 
...
WHERE
  id IN %(ids)s
  AND created_at > %(start_dt)s
''', {
  'ids': tuple(ids), 'start_dt': '2019-10-31 00:00:00'
})

পরীক্ষিত python2.7,pymysql==0.7.11


4
এটি পাইথন 3 এবং মাইএসকিএল-সংযোজক-পাইথন 8.0.21 এর সাথে কাজ করে না। একটি ত্রুটি "পাইথন টিপলকে মাইএসকিউএল টাইপে রূপান্তর করা যায় না" ফিরে আসে।
রুবস

-2

আপনি যদি ব্যবহার করেন Django 2.0 or 2.1এবং Python 3.6, এটি সঠিক উপায়:

from django.db import connection
RESULT_COLS = ['col1', 'col2', 'col3']
RESULT_COLS_STR = ', '.join(['a.'+'`'+i+'`' for i in RESULT_COLS])
QUERY_INDEX = RESULT_COLS[0]

TABLE_NAME = 'test'
search_value = ['ab', 'cd', 'ef']  # <-- a list
query = (
    f'SELECT DISTINCT {RESULT_COLS_STR} FROM {TABLE_NAME} a '
    f'WHERE a.`{RESULT_COLS[0]}` IN %s '
    f'ORDER BY a.`{RESULT_COLS[0]}`;'
)  # <- 'SELECT DISTINCT a.`col1`, a.`col2`, a.`col3` FROM test a WHERE a.`col1` IN %s ORDER BY a.`col1`;'
with connection.cursor() as cursor:
    cursor.execute(query, params=[search_value])  # params is a list with a list as its element

রেফ: https://stackoverflow.com/a/23891759/2803344 https://docs.djangoproject.com/en/2.1/topics/db/sql/#passing-paraters-into-raw


কিছু ভুল হলে দয়া করে আমাকে সংশোধন করুন!
বেল্টার

-2

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

list_to_check = ['A', 'B'] cursor.execute("DELETE FROM foo.bar WHERE baz IN ({})".format(str(list_to_check)[1:-1])

দিয়ে পরীক্ষিত Python=3.6


4
আমি আশঙ্কা করি যে এই সমাধানটি এসকিউএল ইনজেকশন আক্রমণগুলির পক্ষে ঝুঁকিপূর্ণ, কারণ সরবরাহিত list_to_checkএসকিউএল-পলায়ন হচ্ছে না। এ কারণেই মানগুলিকে পরামিতি হিসাবে পাস executeকরা আরও উপযুক্ত। এই সমাধানটি খুব সাবধানতার সাথে ব্যবহার করুন (অর্থাত আপনার অ্যাপ্লিকেশনটির বাইরের দিক থেকে ইনপুট আইডিগুলি প্যারামিটার হিসাবে প্রাপ্ত হয় না), কারণ কেউ আপনার সিস্টেমে আক্রমণ করতে এবং আপনার ডাটাবেস অ্যাক্সেস করতে এটি ব্যবহার করতে পারে।
রাবস

-3

তালিকা উপলব্ধি ব্যবহার করে অন্য একটি সহজ সমাধান:

# creating a new list of strings and convert to tuple
sql_list = tuple([ key.encode("UTF-8") for key in list_of_ids ])

# replace "{}" with "('id1','id2',...'idlast')"
cursor.execute("DELETE FROM foo.bar WHERE baz IN {}".format(sql_list))

-4
list_of_ids = [ 1, 2, 3]
query = "select * from table where x in %s" % str(tuple(list_of_ids))
print query

এটি কিছু ব্যবহারের ক্ষেত্রে কাজ করতে পারে যদি আপনি যে পদ্ধতিতে ক্যোয়ারিং স্ট্রিংটি সম্পন্ন করার জন্য আপনাকে আর্গুমেন্টগুলি দিতে হয় এবং আপনার কাছে কেবল অনুরোধ করতে চান তবে সে সম্পর্কে উদ্বিগ্ন না হতে চান cursror.execute(query)

অন্য উপায় হতে পারে:

"select * from table where x in (%s)" % ', '.join(str(id) for id in list_of_ids)

-7

খুব সহজ: কেবল নীচের গঠনটি ব্যবহার করুন

নিয়ম_আইডি = ["9", "10"]

sql1 = "উপস্থিতি_প্রেমী_স্ট্যাফ থেকে * নির্বাচন করুন" যেখানে আইডি ("+", ".জৌইন (মানচিত্রে (নিয়মিত, নিয়ম_আইডি)) +") "

"," যোগ দিন (মানচিত্র (স্ট্রিং, বিধি_আইডি))


এটি কোথায় স্কিল কোটিং করে এবং এটি বাইন্ড ভেরিয়েবলের পরিবর্তে আক্ষরিক ব্যবহার করে না?
উপস্থাপিত হয়েছে

প্রয়োজন নেই, এটি কেবল সূক্ষ্মভাবে কাজ করে। আপনি পরীক্ষা করতে পারেন কারণ প্রথম ধনুর্বন্ধনী ("9", "10") দিয়ে টুপল গঠন সরাসরি স্ট্রিং হিসাবে রূপান্তরিত হয়েছিল। যা বর্গক্ষেত্র গঠনের সমন্বয় করে। সুতরাং আপনার বানাতে অন্য গঠনের দরকার নেই এটি হল স্কিল অ্যাডজাস্টেবল
মিজানুর রহমান

4
এবং যদি একটি rules_idথাকে "); DROP TABLES Bobby --?
উপস্থাপিত হয়েছে

ইতিমধ্যে "একটি তালিকা জড়িত" নয় "বলেছে ... তাই প্রশ্নের আগে আপনাকে যাচাই করতে হবে
মিজানুর রহমান

বা ব্যবহার করুন: sql1 = "উপস্থিতি_প্রেমী_স্ট্যাফ থেকে * নির্বাচন করুন" যেখানে আইডিতে ("+", "। জোইন (মানচিত্র (টিআরটি, বিধি_আইডি)) +") "
মিজানুর রহমান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.