get upgrade working on sqlite with foreign key naming convention

This commit is contained in:
Min RK
2021-05-12 16:41:56 +02:00
parent 7e46d5d0fc
commit 57f4c08492
2 changed files with 67 additions and 32 deletions

View File

@@ -1,4 +1,5 @@
"""RBAC """
rbac changes for jupyterhub 2.0
Revision ID: 833da8570507 Revision ID: 833da8570507
Revises: 4dc2d5a8c53c Revises: 4dc2d5a8c53c
@@ -14,31 +15,40 @@ depends_on = None
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from jupyterhub import orm
naming_convention = orm.meta.naming_convention
def upgrade(): def upgrade():
# associate spawners and services with their oauth clients # associate spawners and services with their oauth clients
op.add_column( # op.add_column(
'services', sa.Column('oauth_client_id', sa.Unicode(length=255), nullable=True) # 'services', sa.Column('oauth_client_id', sa.Unicode(length=255), nullable=True)
) # )
op.create_foreign_key( for table_name in ('services', 'spawners'):
None, column_name = "oauth_client_id"
'services', target_table = "oauth_clients"
'oauth_clients', target_column = "identifier"
['oauth_client_id'], with op.batch_alter_table(
['identifier'], table_name,
ondelete='SET NULL', schema=None,
) ) as batch_op:
op.add_column( batch_op.add_column(
'spawners', sa.Column('oauth_client_id', sa.Unicode(length=255), nullable=True) sa.Column('oauth_client_id', sa.Unicode(length=255), nullable=True),
) )
op.create_foreign_key( batch_op.create_foreign_key(
None, naming_convention["fk"]
'spawners', % dict(
'oauth_clients', table_name=table_name,
['oauth_client_id'], column_0_name=column_name,
['identifier'], referred_table_name=target_table,
ondelete='SET NULL', ),
) target_table,
[column_name],
[target_column],
ondelete='SET NULL',
)
# FIXME, maybe: currently drops all api tokens and forces recreation! # FIXME, maybe: currently drops all api tokens and forces recreation!
# this ensures a consistent database, but requires: # this ensures a consistent database, but requires:
@@ -57,17 +67,32 @@ def upgrade():
def downgrade(): def downgrade():
for table_name in ('services', 'spawners'):
column_name = "oauth_client_id"
target_table = "oauth_clients"
target_column = "identifier"
op.drop_constraint(None, 'spawners', type_='foreignkey') with op.batch_alter_table(
op.drop_column('spawners', 'oauth_client_id') table_name,
op.drop_constraint(None, 'services', type_='foreignkey') schema=None,
op.drop_column('services', 'oauth_client_id') naming_convention=orm.meta.naming_convention,
) as batch_op:
batch_op.drop_constraint(
naming_convention["fk"]
% dict(
table_name=table_name,
column_0_name=column_name,
referred_table_name=target_table,
),
type_='foreignkey',
)
batch_op.drop_column(column_name)
# delete OAuth tokens for non-jupyterhub clients # delete OAuth tokens for non-jupyterhub clients
# drop new columns from api tokens # drop new columns from api tokens
op.drop_constraint(None, 'api_tokens', type_='foreignkey') # op.drop_constraint(None, 'api_tokens', type_='foreignkey')
op.drop_column('api_tokens', 'session_id') # op.drop_column('api_tokens', 'session_id')
op.drop_column('api_tokens', 'client_id') # op.drop_column('api_tokens', 'client_id')
# FIXME: only drop tokens whose client id is not 'jupyterhub' # FIXME: only drop tokens whose client id is not 'jupyterhub'
# until then, drop all tokens # until then, drop all tokens

View File

@@ -16,12 +16,12 @@ from sqlalchemy import Boolean
from sqlalchemy import Column from sqlalchemy import Column
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy import DateTime from sqlalchemy import DateTime
from sqlalchemy import Enum
from sqlalchemy import event from sqlalchemy import event
from sqlalchemy import exc from sqlalchemy import exc
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy import inspect from sqlalchemy import inspect
from sqlalchemy import Integer from sqlalchemy import Integer
from sqlalchemy import MetaData
from sqlalchemy import or_ from sqlalchemy import or_
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy import Table from sqlalchemy import Table
@@ -115,7 +115,17 @@ class JSONList(JSONDict):
return value return value
Base = declarative_base() meta = MetaData(
naming_convention={
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
)
Base = declarative_base(metadata=meta)
Base.log = app_log Base.log = app_log