ফ্লাস্ক-এসকিউএএলএলএলচেমি অ্যাপে কীভাবে কাঁচা এসকিউএল কার্যকর করা যায়


219

কীভাবে আপনি এসকিউএলএলকেমে কাঁচা এসকিউএল চালাবেন?

আমার কাছে একটি পাইথন ওয়েব অ্যাপ্লিকেশন রয়েছে যা এসকিউএএলএলচেমির মাধ্যমে ডেটাবেজে ফ্লাস্ক এবং ইন্টারফেসগুলিতে চলে।

আমার কাঁচা এসকিউএল চালানোর জন্য একটি উপায় দরকার। ক্যোয়ারিতে ইনলাইন ভিউগুলির সাথে একাধিক টেবিল যোগ দেয়।

আমি চেষ্টা করেছিলাম:

connection = db.session.connection()
connection.execute( <sql here> )

তবে আমি গেটওয়ে ত্রুটিগুলি পেতে থাকি।


5
আমি এর আগে দেখেছি কিন্তু আপডেট চালানোর বিষয়ে টিউটোরিয়ালটি আমি খুঁজে পাইনি। আমি বরং সিনট্যাক্সটি শিখতে এবং একটি দীর্ঘ দীর্ঘ (প্রায় 20 লাইন) এসকিউএল কোয়েরিটি গোপন করতাম না।
starwing123

103
@ মারকাস আন্টারওয়াদিজিটর আমি এটি ভাবতাম, তবে এখন আমি দৃ strongly়ভাবে একমত নই। কাঁচা, সঠিকভাবে প্যারামিট্রাইজড এসকিউএল সাধারণত উত্পন্ন ফাংশন কল এবং অবজেক্টগুলির গুচ্ছের চেয়ে পড়া এবং বজায় রাখা খুব সহজ। এটি ওআরএমকে সঠিক সিনট্যাক্স তৈরি করতে (যদিও এটি এমনকি সম্ভব) তৈরি করার জন্য হুপের মাধ্যমে ঝাঁপিয়ে না পড়ে ডেটাবেজের সম্পূর্ণ ক্ষমতাও সরবরাহ করে এবং ওআরএমকে অপ্রত্যাশিত কাজ থেকে বিরত রাখে। আপনি এই প্রশ্নটি জিজ্ঞাসা করতে পারেন, "তবে কেন এসকিউএলএলকেমি ব্যবহার করবেন না?", এবং আমার কাছে একমাত্র উত্তর, "বিদ্যমান অ্যাপ্লিকেশনটি এটি ব্যবহার করে এবং সবকিছু পরিবর্তন করা খুব ব্যয়বহুল।"
jpmc26

4
@ jpmc26 আপনার মন্তব্যে আপলোড করেছেন S এসকিউএল প্রেমী হিসাবে, একটি দায়িত্বজ্ঞানহীন আলকেমিস্টকে "ডাটাবেসের চাবি তুলে দেওয়া" এবং ওআরএমের পাশে ঝুঁকে ঝোঁক দেওয়ার ধারণাটি নিয়ে আমার খুব কষ্ট হয়েছে :) এটি হচ্ছে বলেছে যে আমি কিছু নির্দিষ্ট উপাদান যেমন, ব্যবহারকারী রেজিস্ট্রেশন / পরিচালনা, এবং বোতামগুলির সিকোয়েন্স সহ টেবিলগুলির প্রজন্মকে ত্বরান্বিত করতে আগ্রহী, যার জন্য আমি ক্রিয়াগুলি + এসকিউএল কোড করতে পারি। আপনি কি এমন কিছু ওআরএম-সংশয়ী-বান্ধব সরঞ্জাম পেয়েছেন যা পাইথন ফ্রেমওয়ার্কে আপনার জন্য ভাল কাজ করে?
zx81

@ jpmc26 আপনি কেবলমাত্র এসকিউএল বা সি # ডাপারের মতো ঘনিষ্ঠভাবে ব্যবহার করতে পাইথন ফ্রেমওয়ার্কটিতে কী ব্যবহার করবেন? পাইথনের ওয়েব ফ্রেমওয়ার্কে আমি যা দেখি তা সবই আমি এসকিউএএলএলএকমি ব্যবহার করতে চাই এবং আমি একটি ওআরএম পছন্দ করি না এবং যদি আমি এটি ব্যবহার করি তবে এটি অত্যন্ত ন্যূনতম।
জহ্নি

@ জোহনি আমার নিজের চেষ্টা করার সুযোগ হয়নি, তবে কাঁচা ডাটাবেস সংযোগের লাইব্রেরি সম্ভবত যথেষ্ট। উদাহরণস্বরূপ, psycopg2 এক্সিকিউটেবল-এর পাথ যে ফিরতি হয়েছে namedtupleএবং dict: সরাসরি initd.org/psycopg/docs/extras.html
jpmc26

উত্তর:


310

আপনি চেষ্টা করেছেন:

result = db.engine.execute("<sql here>")

বা:

from sqlalchemy import text

sql = text('select name from penguins')
result = db.engine.execute(sql)
names = [row[0] for row in result]
print names

7
আপনি যদি একটি সন্নিবেশ বা আপডেট করেন তবে লেনদেনটি কীভাবে করবেন?
ডেভিড এস

14
আপনি যদি কাঁচা এসকিউএল ব্যবহার করেন তবে আপনি লেনদেন নিয়ন্ত্রণ করতে পারেন, তাই আপনাকে নিজে BEGINএবং COMMITবিবৃতি ইস্যু করতে হবে ।
মিগুয়েল

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

27
db.engine.execute(text("<sql here>")).execution_options(autocommit=True))এটি কার্যকর এবং সংঘবদ্ধ।
দেবী

8
@ মিগুয়েল "আপনি যদি কাঁচা এসকিউএল ব্যবহার করেন তবে আপনি লেনদেন নিয়ন্ত্রণ করেন, সুতরাং আপনাকে নিজেই শুরু করুন বিজিআইএন এবং কমিট স্টেটমেন্টগুলি।" এই কেবল সত্য নয়। আপনি একটি সেশন অবজেক্ট সহ কাঁচা এসকিউএল ব্যবহার করতে পারেন। এই মন্তব্যটি কেবলমাত্র লক্ষ্য করা গেছে, তবে কাঁচা এসকিউএল সহ একটি সেশন কীভাবে ব্যবহার করতে হয় তার জন্য আপনি আমার উত্তর দেখতে পারেন।
jpmc26

180

এসকিউএল আলকেমি সেশন অবজেক্টগুলির নিজস্ব executeপদ্ধতি রয়েছে:

result = db.session.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})

আপনার সমস্ত অ্যাপ্লিকেশন প্রশ্নগুলি কাঁচা এসকিউএল কিনা তা সেশন অবজেক্টের মধ্য দিয়ে যাওয়া উচিত। এটি নিশ্চিত করে যে ক্যোয়ারীগুলি কোনও লেনদেনের মাধ্যমে সঠিকভাবে পরিচালিত হয়েছে , যা একই অনুরোধে একাধিক প্রশ্নের প্রতিশ্রুতিবদ্ধ বা একক ইউনিট হিসাবে ফিরে যেতে সহায়তা করে। ইঞ্জিন বা সংযোগ ব্যবহার করে লেনদেনের বাইরে যাওয়া আপনাকে সূক্ষ্মতার অনেক বেশি ঝুঁকিতে ফেলে, সম্ভবত ত্রুটিযুক্ত ডেটা দিয়ে আপনাকে ছেড়ে দিতে পারে এমন বাগগুলি সনাক্ত করা খুব শক্ত। প্রতিটি অনুরোধটি কেবল একটি লেনদেনের সাথে জড়িত হওয়া উচিত এবং এটি ব্যবহার করা db.sessionআপনার আবেদনের ক্ষেত্রে নিশ্চিত হবে ensure

প্যারামিটারাইজড কোয়েরিগুলিরexecute জন্য ডিজাইন করা হয়েছে তাও নোট করুন । :valএসকিউএল ইঞ্জেকশন আক্রমণ থেকে নিজেকে রক্ষা করতে কোয়েরিতে থাকা কোনও ইনপুটগুলির জন্য উদাহরণস্বরূপ প্যারামিটারগুলি ব্যবহার করুন । আপনি এই প্যারামিটারগুলির জন্য dictদ্বিতীয় আর্গুমেন্ট হিসাবে মান প্রদান করতে পারেন , যেখানে প্রতিটি কী প্যারামিটারের নাম যা ক্যোয়ারীতে প্রদর্শিত হবে। প্যারামিটারের সঠিক বাক্য গঠন নিজেই আপনার ডাটাবেসের উপর নির্ভর করে ভিন্ন হতে পারে, তবে সমস্ত প্রধান রিলেশনাল ডাটাবেসগুলি কোনও না কোনও আকারে তাদের সমর্থন করে।

ধরে নেওয়া যাক এটি একটি এর SELECTক্যোয়ারী, এই ফিরে আসবে একটি iterable এর RowProxyঅবজেক্ট।

আপনি বিভিন্ন কৌশল সহ পৃথক কলামগুলি অ্যাক্সেস করতে পারেন:

for r in result:
    print(r[0]) # Access by positional index
    print(r['my_column']) # Access by column name as a string
    r_dict = dict(r.items()) # convert to dict keyed by column names

ব্যক্তিগতভাবে, আমি ফলাফলগুলিকে এসগুলিতে রূপান্তর করতে পছন্দ করি namedtuple:

from collections import namedtuple

Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
    print(r.my_column)
    print(r)

আপনি যদি ফ্লাস্ক-এসকিউএএলএলএকএলএমই এক্সটেনশন ব্যবহার করছেন না, আপনি এখনও সহজেই একটি সেশন ব্যবহার করতে পারেন:

import sqlalchemy
from sqlalchemy.orm import sessionmaker, scoped_session

engine = sqlalchemy.create_engine('my connection string')
Session = scoped_session(sessionmaker(bind=engine))

s = Session()
result = s.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})

একটি নির্বাচন একটি রেজাল্টপ্রক্সি ফিরিয়ে দেবে।
অ্যালান বি

@ অ্যালানবি হ্যাঁ আমি আমার শব্দগুলিকে খারাপভাবে বেছে নিয়েছি যখন আমি এটিকে সিক্যুয়েন্স বলি, এটি বোঝায় এটি সিকোয়েন্স প্রোটোকলটি প্রয়োগ করে। আমি সংশোধন করেছি এবং স্পষ্ট করে দিয়েছি। ধন্যবাদ।
jpmc26

@ jpmc26 db.session.close () এর মতো ক্যোয়ারি চালানোর পরে সেশনটি বন্ধ করা উচিত? এবং এরপরেও কি সংযোগ পুলিংয়ের সুবিধা থাকবে?
রবি মালহোত্রা

58

ডক্স: এসকিউএল এক্সপ্রেশন ভাষা টিউটোরিয়াল - পাঠ্য ব্যবহার করে

উদাহরণ:

from sqlalchemy.sql import text

connection = engine.connect()

# recommended
cmd = 'select * from Employees where EmployeeGroup = :group'
employeeGroup = 'Staff'
employees = connection.execute(text(cmd), group = employeeGroup)

# or - wee more difficult to interpret the command
employeeGroup = 'Staff'
employees = connection.execute(
                  text('select * from Employees where EmployeeGroup = :group'), 
                  group = employeeGroup)

# or - notice the requirement to quote 'Staff'
employees = connection.execute(
                  text("select * from Employees where EmployeeGroup = 'Staff'"))


for employee in employees: logger.debug(employee)
# output
(0, 'Tim', 'Gurra', 'Staff', '991-509-9284')
(1, 'Jim', 'Carey', 'Staff', '832-252-1910')
(2, 'Lee', 'Asher', 'Staff', '897-747-1564')
(3, 'Ben', 'Hayes', 'Staff', '584-255-2631')

1
স্ক্যালচেমি ডক্সের লিঙ্কটি পুরানো বলে মনে হচ্ছে। এটি আরও সাম্প্রতিক: ডকস.সেক্লাচেমি.আর.জি.ইন
কার্ল

1
আমরা জিজ্ঞাসা করতে পারি কেন আমরা ব্যবহার করছি ==?
নাম জি ভিইউ

1
@ জ্যাক বার্গার আপনাকে ধন্যবাদ এই উত্তরের সন্ধানে আমি প্রায় একদিন নষ্ট করেছি। আমি কেবল পাঠ্যে রূপান্তর না করেই সরাসরি এসকিএল চালাচ্ছিলাম। যখনই আমার যেখানে ক্লজটিতে% শিক্ষার্থী ছিল তখনই এটি ত্রুটি ছুঁড়ে মারছিল। আপনার উত্তরের জন্য একটি বড় প্রশংসা।
সুরেশ কুমার

1
@ নামজিভিউ, কারণ বেশিরভাগ প্রোগ্রামিং ভাষার মতোই =সাধারণত একটি মান নির্ধারণের জন্য সংরক্ষিত থাকে ; যেখানে মানগুলির তুলনা করার== জন্য সংরক্ষিত রয়েছে
জ্যাক বার্গার

2
@ জ্যাকবার্গার এর জন্য আপনার কি লিঙ্ক আছে? এসকিউএল এমন ভাষা নয় এবং এসকিউএএলএলএকচেমি ডক্সের দ্বারা বিচার করা এটি এমন নয়।
জোহানোদো

36

ব্যবহার করে আপনি নির্বাচন এসকিউএল কোয়েরি এর ফলাফল পেতে পারেন from_statement()এবং text()হিসাবে দেখানো এখানে । আপনাকে এইভাবে টিপলগুলি মোকাবেলা করতে হবে না। শ্রেণীর Userটেবিলের নাম থাকার উদাহরণ হিসাবে usersআপনি চেষ্টা করতে পারেন,

from sqlalchemy.sql import text
.
.
.
user = session.query(User).from_statement(
    text("SELECT * FROM users where name=:name")).\
    params(name='ed').all()

return user

15
result = db.engine.execute(text("<sql here>"))

কার্যকর করে <sql here>তবে আপনি না থাকলে তা প্রতিশ্রুতি দেয় নাautocommit মোডে । সুতরাং, সন্নিবেশ এবং আপডেটগুলি ডাটাবেসে প্রতিফলিত হবে না।

পরিবর্তনের পরে প্রতিশ্রুতিবদ্ধ, করতে

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))

2

এটি ফ্লাস্ক শেল থেকে এসকিউএল কোয়েরিটি কীভাবে চালানো যায় তার একটি সরল উত্তর

প্রথমে, আপনার মডিউলটি মানচিত্র করুন (যদি আপনার মডিউল / অ্যাপ্লিকেশনটি মূল ফোল্ডারে ম্যানেজ.পি থাকে এবং আপনি যদি ইউনিক্স অপারেটিং সিস্টেমের মধ্যে থাকেন), চালান:

export FLASK_APP=manage

ফ্লাস্ক শেল চালান

flask shell

আমাদের যা প্রয়োজন তা আমদানি করুন ::

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
from sqlalchemy import text

আপনার ক্যোয়ারী চালান:

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))

এটি বর্তমানে ডেটাবেস সংযোগ ব্যবহার করে যার অ্যাপ্লিকেশন রয়েছে।


0

আপনি ব্যবহার চেষ্টা connection.execute(text( <sql here> ), <bind params here> )করুন এবং বাঁধুন পরামিতি বর্ণনা অনুযায়ী ডক্সে ? এটি অনেকগুলি প্যারামিটার বিন্যাস এবং কার্য সম্পাদন সমস্যার সমাধান করতে সহায়তা করতে পারে। সম্ভবত গেটওয়ে ত্রুটি একটি সময়সীমা? বাইন্ড প্যারামিটারগুলিতে জটিল প্রশ্নগুলি যথেষ্ট দ্রুত কার্যকর করা যায়।


2
ডক্স অনুসারে , এটি হওয়া উচিত connection.execute(text(<sql here>), <bind params> )bind paramsথাকা উচিত নয় text()এক্সিকিউট () পদ্ধতিতে বাইন্ড প্যারামিটারগুলিতে খাওয়ানো
জ্যাক বার্গার

জ্যাকের লিঙ্কটি নষ্ট হয়ে গেছে। আমার মনে হয় এটি এখনই প্রাসঙ্গিক ইউআরএল: ডকসস.সেকলচেমি.আর.ইন
কোর

-1

আপনি tuples এড়াতে চান তাহলে, অন্য উপায় কল করে হয় first, oneবা allপদ্ধতি:

query = db.engine.execute("SELECT * FROM blogs "
                           "WHERE id = 1 ")

assert query.first().name == "Welcome to my blog"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.