kuroの覚え書き

96の個人的覚え書き

MySQLとpythonの連携

MySQLpython(SQLAlchemy)でのお作法の違いをまとめておこう

  • tableにRow(行)を追加する

MySQL

mysql > INSERT INTO users (name, id) VALUES('kuro', 1);

Python

>>> user_kuro = User(username='kuro', id=1)
>>> db.session.add(user_kuro)
>>> db.session.commit()
  • 変更する場合

kuroをblackに変える
MySQL

mysql > UPDATE users SET username='black' WHERE username='kuro'

Python

>>> user_kuro.username = 'black'
>>> db.session.add(user_kuro)
>>> db.session.commit()

fieldの名前を変えるのはこのスクリプトでは可能なのかどうかわからない。まあユーザーにさせる作業じゃないのでわざわざpythonからやらなくてもいいだろう。field名を変えるならスクリプト自体書き換えなけりゃならないわけだし。
基本的にはmodels.pyで定義したテーブルを新たに作成し、そこに行を書き加えていくことができるスクリプトと考えて良いだろう。
なので既存のデータベースを加工して、そこにフロントエンドとしてスクリプトを乗っけるにはデータベースの整形はSQL文をコマンド入力なりその他のツールで実施しておく必要がありそうだ。



MySQLからやるには

mysql > ALTER TABLE users CHANGE 1000user g1000user CHAR(255);

usersテーブルの1000userフィールドがpythonの変数に入れられないのでg1000userというフィールド名にCHAR(255)型で変更する例。
同様にfieldの増減もMySQLからやる。

mysql> alter table users add pos char(255);
mysql> alter table users add score int;
mysql> alter table users add test FLOAT;

このような感じで。



次に検索
MySQL文だと

mysql > SELECT * FROM users WHERE username='kuro'
+----+----------+---------+------+----------+-------+-------+-------+
| id | username | role_id | sex  | pos      | test  | test2 | score |
+----+----------+---------+------+----------+-------+-------+-------+
|  1 | kuro     |       1 | male | 1:100000 | 0.001 |  NULL |   300 |
+----+----------+---------+------+----------+-------+-------+-------+
1 row in set (0.00 sec)

てな具合に返ってくるのだが

$ python3 venv3/hello.py shell
>>> User.query.filter_by(username='kuro').all()
[<User 'kuro'>]

と返ってくるのがusernameの'kuro'だけとなる。これは
hello.pyのなかで

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    sex = db.Column(db.String(64))
    pos = db.Column(db.String(64))
    test = db.Column(db.Float)
    test2 = db.Column(db.Float)
    score = db.Column(db.Integer)

    def __repr__(self):
        return '<User %r>' % self.username

となっていて、最後の行のself.usernameの部分にusernameとなっているためで、ここをrole_idにすれば

>>> User.query.filter_by(username='kuro').all()
[<User 1>]

という反応になるようだ。
データベースを検索してその結果1行をまるまる取得する方法はどうするのだろうか。