SQLAlchemy를 사용하여 새 데이터베이스를 만드는 방법은 무엇입니까?


103

SQLAlchemy를 사용하면 다음과 같이 Engine 개체가 생성됩니다.

from sqlalchemy import create_engine
engine = create_engine("postgresql://localhost/mydb")

engine인수에 지정된 데이터베이스 create_engine(이 경우 mydb)가 없으면 액세스 가 실패 합니다. 지정된 데이터베이스가없는 경우 SQLAlchemy에 새 데이터베이스를 만들도록 지시 할 수 있습니까?


2
새 데이터베이스를 만들거나 테이블 만 만드시겠습니까? 실제로 데이터베이스를 생성하는 ORM을 많이 보지 못했습니다.
Noufal Ibrahim

4
내가 발견 한
Noufal 이브라힘에게

답변:


97

postgres에서는 일반적으로 세 개의 데이터베이스가 기본적으로 존재합니다. 수퍼 유저 (예 : postgres역할)로 연결할 수있는 경우 postgres또는 template1데이터베이스에 연결할 수 있습니다 . 기본 pg_hba.conf는 이름이 지정된 유닉스 사용자 만 역할 postgres을 사용하도록 허용 postgres하므로 가장 간단한 방법은 해당 사용자가되는 것입니다. 어쨌든 데이터베이스를 만들 권한이있는 사용자로 평소와 같이 엔진을 만듭니다.

>>> engine = sqlalchemy.create_engine("postgres://postgres@/postgres")

engine.execute()그러나 postgres는 트랜잭션 내부에 데이터베이스를 만들 수 없으며 sqlalchemy는 항상 트랜잭션에서 쿼리를 실행하려고하기 때문에 사용할 수 없습니다 . 이 문제를 해결하려면 엔진에서 기본 연결을 가져옵니다.

>>> conn = engine.connect()

그러나 연결은 여전히 ​​트랜잭션 내부에 있으므로 다음을 사용하여 열린 트랜잭션을 종료해야합니다 commit.

>>> conn.execute("commit")

그런 다음 적절한 PostgreSQL 명령을 사용하여 데이터베이스 생성을 진행할 수 있습니다.

>>> conn.execute("create database test")
>>> conn.close()

3
이것은 나를 위해 잘 작동했습니다. 참고로, 내가 할 때 conn.execute('drop database DBWithCaps')모자를 인식하지 못하는 문제가있었습니다. conn.execute('drop database "DBWithCaps"')(따옴표 포함) 잘 작동했습니다.
KobeJohn

PostgreSQL은 인용되지 않는 한 모든 엔티티를 소문자로 예상한다는 것을 알고 있습니다. 따라서 MyColumn을 사용하여 필드를 만든 경우 일부 DB는이를 mycolumn으로 사용합니다. 즉, 당신은 당신의 테이블을 생성하지 않도록하는 방법,하지만 인용 부호를 사용하여 생성 된 경우, 그것은 대소 문자를 구분합니다, 당신은 SQL 문에 액세스 할 때 그래서 당신은 따옴표를 필요도 있습니다.
guyarad

119

SQLAlchemy-UtilsSQLAlchemy에 대한 사용자 지정 데이터 유형 및 다양한 유틸리티 함수를 제공합니다. pip를 사용하여 최신 공식 버전을 설치할 수 있습니다.

pip install sqlalchemy-utils

데이터베이스 헬퍼는 포함 create_database기능 :

from sqlalchemy import create_engine
from sqlalchemy_utils import database_exists, create_database

engine = create_engine("postgres://localhost/mydb")
if not database_exists(engine.url):
    create_database(engine.url)

print(database_exists(engine.url))

2
이 정확한 코드 블록을 시도 할 때이 오류가 발생합니다 : psycopg2.OperationalError: fe_sendauth: no password supplied. 사용하면 "postgres://test:abc123@localhost:5432/test"얻을psycopg2.OperationalError: FATAL: password authentication failed for user "test"
Guus

스팸에 대해 죄송하지만 포트를 9000으로 변경하려고했는데 이제 다음과 같이 표시됩니다."postgres://test:abc123@localhost:9000/test" psycopg2.OperationalError: server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.
Guus

9

다음 기능 을 제공 isolation_level='AUTOCOMMIT'하여 데이터베이스를 생성하는 동안 수동 트랜잭션 관리를 피할 수 create_engine있습니다.

import sqlalchemy

with sqlalchemy.create_engine(
    'postgresql:///postgres',
    isolation_level='AUTOCOMMIT'
).connect() as connection:
    connection.execute('CREATE DATABASE my_database')

또한 데이터베이스가 존재하지 않는지 확실하지 않은 경우 sqlalchemy.exc.ProgrammingError예외 를 억제하여 존재로 인한 데이터베이스 생성 오류를 무시하는 방법이 있습니다 .

import contextlib
import sqlalchemy.exc

with contextlib.suppress(sqlalchemy.exc.ProgrammingError):
    # creating database as above

데이터베이스를 지정하지 않고 progres 서버에 연결할 수없는 것 같습니다. 따라서 기본 "postgres"데이터베이스에 연결하여 db 생성 명령을 실행하고 싶을 것입니다. 그렇지 않으면 기본 "user"에 연결을 시도합니다. "데이터베이스가 존재하지 않으면 불평합니다.
Acorn

0

database_exists데이터베이스가 존재하는지 확인할 때마다이 database_exists(engine.url):오류가 발생 하지 않으면 위의 제안을 얻을 수 없습니다 .

InterfaceError ( '(pyodbc.InterfaceError) (\'28000 \ ', u \'[28000] [Microsoft] [SQL Server Native Client 11.0] [SQL Server] \\ 'myUser \\'사용자가 로그인하지 못했습니다. (18456) (SQLDriverConnect); [28000] [Microsoft] [SQL Server Native Client 11.0] [SQL Server] 로그인에서 요청한 "MY_DATABASE"데이터베이스를 열 수 없습니다. 로그인에 실패했습니다. (4060); [28000] [Microsoft] [SQL Server Native Client 11.0] [SQL Server] \\ 'myUser \\'사용자가 로그인하지 못했습니다. (18456); [28000] [Microsoft] [SQL Server Native Client 11.0] [SQL Server] 로그인에서 요청한 "MY_DATABASE"데이터베이스를 열 수 없습니다. . 로그인에 실패했습니다. (4060) \ ')',)

또한 contextlib/suppress작동하지 않았고 사용하지 않으므로 postgres데이터베이스가 SQL Server에 이미 존재하는 경우 예외를 무시하기 위해 이렇게했습니다.

import logging
import sqlalchemy

logging.basicConfig(filename='app.log', format='%(asctime)s-%(levelname)s-%(message)s', level=logging.DEBUG)
engine = create_engine('mssql+pyodbc://myUser:mypwd@localhost:1234/MY_DATABASE?driver=SQL+Server+Native+Client+11.0?trusted_connection=yes', isolation_level = "AUTOCOMMIT")

try: 
    engine.execute('CREATE DATABASE ' + a_database_name)
except Exception as db_exc:
    logging.exception("Exception creating database: " + str(db_exc))  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.