from sqlalchemy.sql import select s = select([users]) result = conn.execute(s) -- 2018-12-24 14:16:11,363 INFO sqlalchemy.engine.base.Engine SELECT users.id, users.name, users.fullname FROM users 2018-12-24 14:16:11,363 INFO sqlalchemy.engine.base.Engine ()
結果のパース。タプルライクに取得。
1 2 3 4 5
for row in result: print(row) -- (1, 'jack', 'Jack Jones') (2, 'wendy', 'Wendy Williams')
辞書ライクに取得。
1 2 3 4 5
result = conn.execute(s) row = result.fetchone() print("name:", row['name'], "; fullname:", row['fullname']) -- name: jack ; fullname: Jack Jones
s = select([users.c.fullname]).select_from( users.join(addresses, addresses.c.email_address.like(users.c.name + '%')) ) conn.execute(s).fetchall() -- 2018-12-25 12:45:29,919 INFO sqlalchemy.engine.base.Engine SELECT users.fullname FROM users JOIN addresses ON addresses.email_address LIKE users.name || ? 2018-12-25 12:45:29,919 INFO sqlalchemy.engine.base.Engine ('%',) [('Jack Jones',), ('Jack Jones',), ('Wendy Williams',)]
outer join
1 2 3 4
print(select([users.c.fullname]).select_from(users.outerjoin(addresses))) -- SELECT users.fullname FROM users LEFT OUTER JOIN addresses ON users.id = addresses.user_id
変数バインド
単純な例
1 2 3 4 5 6 7 8
from sqlalchemy.sql import bindparam s = users.select(users.c.name.like(bindparam('username', type_=String) + text("'%'"))) conn.execute(s, username='wendy').fetchall() -- 2018-12-25 13:34:19,392 INFO sqlalchemy.engine.base.Engine SELECT users.fullname FROM users LEFT OUTER JOIN addresses ON users.id = addresses.user_id 2018-12-25 13:34:19,392 INFO sqlalchemy.engine.base.Engine () [('Jack Jones',), ('Jack Jones',), ('Wendy Williams',), ('Wendy Williams',)]
バインドした変数は複数回使用できる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
s = select([users, addresses]).\ where( or_( users.c.name.like( bindparam('name', type_=String) + text("'%'")), addresses.c.email_address.like( bindparam('name', type_=String) + text("'@%'")) ) ).\ select_from(users.outerjoin(addresses)).\ order_by(addresses.c.id) conn.execute(s, name='jack').fetchall() -- 2018-12-25 13:43:43,880 INFO sqlalchemy.engine.base.Engine SELECT users.id, users.name, users.fullname, addresses.id, addresses.user_id, addresses.email_address FROM users LEFT OUTER JOIN addresses ON users.id = addresses.user_id WHERE users.name LIKE ? || '%' OR addresses.email_address LIKE ? || '@%' ORDER BY addresses.id 2018-12-25 13:43:43,880 INFO sqlalchemy.engine.base.Engine ('jack', 'jack') [(1, 'jack', 'Jack Jones', 1, 1, 'jack@yahoo.com'), (1, 'jack', 'Jack Jones', 2, 1, 'jack@msn.com')]
>>> from app import db /usr/local/lib/python3.6/dist-packages/flask_sqlalchemy/__init__.py:794: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning. 'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and ' >>> db.create_all() >>> from app import User >>> admin = User(username='admin', email='admin@example.com') >>> guest = User(username='guest', email='guest@example.com') >>> db.session.add(admin) >>> db.session.add(guest) >>> db.session.commit() >>> User.query.all() [<User 'admin'>, <User 'guest'>] >>> User.query.filter_by(username='admin').first() <User 'admin'>
@app.route('/user/<username>') def profile(username): return '{}\'s profile'.format(username) @app.route('/post/<int:post_id>') def post(post_id): # show the post with the given id, the id is an integer return 'Post %d' % post_id @app.route('/path/<path:subpath>') def subpath(subpath): # show the subpath after /path/ return 'Subpath %s' % subpath @app.route('/projects/') def projects(): return 'The project page' @app.route('/about') def about(): return 'The about page'
# Set the secret key to some random bytes. Keep this really secret! app.secret_key = b'_5#y2L"F4Q8z\n\xec]/' @app.route('/login', methods=['POST', 'GET']) def login(): error = None if request.method == 'POST': if valid_login(request.form['username'], request.form['password']): session['username'] = request.form['username'] return redirect(url_for('welcome')) else: error = 'Invalid username/password' # the code below is executed if the request method # was GET or the credentials were invalid return render_template('login.html', error=error)
@app.route('/welcome') def welcome(): if 'username' in session: return render_template('welcome.html', username=session['username']) else: return redirect(url_for('login'))
$ mkdir -p ~/Sources/docker_flask/nginx_spa $ cd ~/Sources/docker_flask/nginx_spa $ cat << EOF > Dockerfile fROM tiangolo/uwsgi-nginx-flask:python3.7 eNV STATIC_INDEX 1 cOPY ./app /app eOF $ mkdir app $ cat << EOF > app/main.py import os from flask import Flask, send_file app = Flask(__name__) @app.route("/hello") def hello(): return "Hello World from Flask" @app.route("/") def main(): index_path = os.path.join(app.static_folder, 'index.html') return send_file(index_path) # Everything not declared before (not a Flask route / API endpoint)... @app.route('/<path:path>') def route_frontend(path): # ...could be a static file needed by the front end that # doesn't use the `static` path (like in `<script src="bundle.js">`) file_path = os.path.join(app.static_folder, path) if os.path.isfile(file_path): return send_file(file_path) # ...or should be handled by the SPA's "router" in front end else: index_path = os.path.join(app.static_folder, 'index.html') return send_file(index_path) if __name__ == "__main__": # Only for debugging while developing app.run(host='0.0.0.0', debug=True, port=80) eOF
$ cat Dockerfile froM tiangolo/uwsgi-nginx-flask:python3.7
run apt-get update run pip install pyopenssl
copY ./app /app
main.pyを以下のように修正し、アドホックなSSL対応を試せるようにする。
1 2 3 4 5 6 7 8 9 10 11 12
$ cat app/app/main.py from flask import Flask
app = Flask(__name__)
from .core import app_setup
if __name__ == "__main__": # Only for debugging while developing # app.run(host='0.0.0.0', debug=True, port=80) app.run(host='0.0.0.0', debug=True, ssl_context='adhoc')
PixieDust lets you bring robust Python visualization options to your Scala notebooks.
1
Scala Bridge. Use Scala directly in your Python notebook. Variables are automatically transfered from Python to Scala and vice-versa. Learn more.
1
Spark progress monitor. Track the status of your Spark job. No more waiting in the dark. Notebook users can now see how a cell's code is running behind the scenes.
$ jupyter pixiedust install Step 1: PIXIEDUST_HOME: /home/dobachi/pixiedust Keep y/n [y]? y Step 2: SPARK_HOME: /home/dobachi/pixiedust/bin/spark Keep y/n [y]? y Directory /home/dobachi/pixiedust/bin/spark does not contain a valid SPARK install Download Spark y/n [y]? y What version would you like to download? 1.6.3, 2.0.2, 2.1.0, 2.2.0, 2.3.0 [2.3.0]: SPARK_HOME will be set to /home/dobachi/pixiedust/bin/spark/spark-2.3.0-bin-hadoop2.7 Downloading Spark 2.3.0 Traceback (most recent call last):
(snip)
File "/home/dobachi/.conda/envs/PixieDustExample/lib/python3.7/site-packages/install/createKernel.py", line 408, in download_spark temp_file = self.download_file(spark_download_url) File "/home/dobachi/.conda/envs/PixieDustExample/lib/python3.7/site-packages/install/createKernel.py", line 455, in download_file raise Exception("{}".format(response.status_code)) Exception: 404
#################################################################################################### # Congratulations: Kernel Python-with-Pixiedust_Spark-2.3 was successfully created in /home/dobachi/.local/share/jupyter/kernels/pythonwithpixiedustspark23 # You can start the Notebook server with the following command: # jupyter notebook /home/dobachi/pixiedust/notebooks ####################################################################################################