개발/Python

[파이썬] SQLAlchemy에서 create_all() 테이블 생성되지 않습니다.

MinorMan 2022. 10. 11. 03:50
반응형

<질문>

PostgreSQL과 SQLAlchemy를 통합하려고 하는데 SQLAlchemy.create_all()이 내 모델에서 테이블을 생성하지 않습니다.

내 코드:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://login:pass@localhost/flask_app'
db = SQLAlchemy(app)
db.create_all()
db.session.commit()

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email

    def __repr__(self):
        return '' % self.username

admin = User('admin', 'admin@example.com')
guest = User('guest', 'guest@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
users = User.query.all()
print users        

그러나이 오류가 발생합니다.sqlalchemy.exc.ProgrammingError: (ProgrammingError) relation "user" does not exist

이 문제를 해결하려면 어떻게 해야 하나요?


<답변1>

당신은 전에 당신의 모델 클래스를 넣어야합니다create_all() 다음과 같이 호출하십시오.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://login:pass@localhost/flask_app'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email

    def __repr__(self):
        return '' % self.username

db.create_all()
db.session.commit()

admin = User('admin', 'admin@example.com')
guest = User('guest', 'guest@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
users = User.query.all()
print users

모델이 별도의 모듈에서 선언된 경우 호출하기 전에 모델을 가져옵니다.create_all().

말해,User 모델은 이라는 파일에 있습니다.models.py,

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://login:pass@localhost/flask_app'
db = SQLAlchemy(app)

# See important note below
from models import User

db.create_all()
db.session.commit()

admin = User('admin', 'admin@example.com')
guest = User('guest', 'guest@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
users = User.query.all()
print users

중요 사항: 초기화 후에 모델을 가져오는 것이 중요합니다.db 그 이후로, 당신의models.py _당신은 또한 수입해야합니다db 이 모듈의 개체입니다.


<답변2>

이것이 아마도 주된 이유는 아닐 것입니다.create_all() 메서드 호출은 사람들에게는 작동하지 않지만 저에게는 다양한 자습서의 자갈이 깔린 지침에 요청 컨텍스트에서 내 db를 생성하는 것과 같은 내용이 있습니다. 즉, 다음과 같습니다.

# lib/db.py
from flask import g, current_app
from flask_sqlalchemy import SQLAlchemy

def get_db():
  if 'db' not in g:
    g.db = SQLAlchemy(current_app)
  return g.db

또한 create_all도 수행하는 별도의 cli 명령이 있습니다.

# tasks/db.py
from lib.db import get_db

@current_app.cli.command('init-db')
def init_db():
  db = get_db()
  db.create_all()

나는 또한 응용 프로그램 공장을 사용하고 있습니다.

cli 명령이 실행되면 새 앱 컨텍스트가 사용됩니다. 즉, 새 db가 사용됩니다. 게다가, 이 세계에서 init_db 메소드의 import 모델은 아무 것도 하지 않습니다. 왜냐하면 당신의 모델 파일이 이미 로드되었을 수 있기 때문입니다(그리고 별도의 db와 연결되었을 수 있습니다).

내가 찾아온 수정 사항은 db가 단일 전역 참조인지 확인하는 것이었습니다.

# lib/db.py
from flask import g, current_app
from flask_sqlalchemy import SQLAlchemy

db = None
def get_db():
  global db
  if not db:
    db = SQLAlchemy(current_app)
  return db

나는 이것이 여러 스레드에서 db에 대한 요청이 안전하다는 것을 의미하는지 이해하기 위해 flask, sqlalchemy 또는 flask-sqlalchemy에 대해 충분히 깊이 파고 들지 않았지만, 이 글을 읽고 있다면 이러한 내용을 이해하는 아기 단계에 갇히게 될 것입니다. 개념도.


<답변3>

누군가가 각 모델 전용 파일을 사용하여 테이블을 생성하는 데 문제가 있는 경우 해당 함수가 선언된 파일과 다른 파일에서 "create_all" 함수를 실행하는 것에 주의하십시오. 따라서 파일 시스템이 다음과 같은 경우:

Root  
--app.py     <-- file from which app will be run
--models
----user.py      <-- file with "User" model
----order.py    <-- file with "Order" model
----database.py <-- file with database and "create_all" function declaration

app.py에서 "create_all" 함수를 호출할 때 주의하십시오.

이 개념은 에 대한 답변으로 더 잘 설명됩니다.this thread 에 의해 게시@SuperShoot

반응형