Revert db checks in launcher that caused instability with imports. Resolve #3790
This commit is contained in:
parent
4bc6abfdb9
commit
baf9a4068b
2 changed files with 62 additions and 84 deletions
|
|
@ -50,6 +50,7 @@ This upgrade requires running `evennia migrate` on your existing database
|
||||||
- [Fix][pull3768]: Make sure the `CmdCopy` command copies object categories,
|
- [Fix][pull3768]: Make sure the `CmdCopy` command copies object categories,
|
||||||
since otherwise plurals were lost (jaborsh)
|
since otherwise plurals were lost (jaborsh)
|
||||||
- [Fix][issue3788]: `GLOBAL_SCRIPTS.all()` raised error (Griatch)
|
- [Fix][issue3788]: `GLOBAL_SCRIPTS.all()` raised error (Griatch)
|
||||||
|
- [Fix][issue3790]: Fix migration issue due to new db init-check code in launcher (Griatch)
|
||||||
- Fix: `options` setting `NOPROMPTGOAHEAD` was not possible to set (Griatch)
|
- Fix: `options` setting `NOPROMPTGOAHEAD` was not possible to set (Griatch)
|
||||||
- Fix: Make `\\` properly preserve one backlash in funcparser (Griatch)
|
- Fix: Make `\\` properly preserve one backlash in funcparser (Griatch)
|
||||||
- Fix: The testing 'echo' inputfunc didn't work correctly; now returns both args/kwargs (Griatch)
|
- Fix: The testing 'echo' inputfunc didn't work correctly; now returns both args/kwargs (Griatch)
|
||||||
|
|
@ -90,6 +91,7 @@ This upgrade requires running `evennia migrate` on your existing database
|
||||||
[issue3688]: https://github.com/evennia/evennia/issues/3688
|
[issue3688]: https://github.com/evennia/evennia/issues/3688
|
||||||
[issue3687]: https://github.com/evennia/evennia/issues/3687
|
[issue3687]: https://github.com/evennia/evennia/issues/3687
|
||||||
[issue3788]: https://github.com/evennia/evennia/issues/3788
|
[issue3788]: https://github.com/evennia/evennia/issues/3788
|
||||||
|
[issue3790]: https://github.com/evennia/evennia/issues/3790
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ RECREATED_MISSING = """
|
||||||
|
|
||||||
ERROR_DATABASE = """
|
ERROR_DATABASE = """
|
||||||
ERROR: Your database does not exist or is not set up correctly.
|
ERROR: Your database does not exist or is not set up correctly.
|
||||||
Missing tables: {missing_tables}
|
(error was '{traceback}')
|
||||||
|
|
||||||
If you think your database should work, make sure you are running your
|
If you think your database should work, make sure you are running your
|
||||||
commands from inside your game directory. If this error persists, run
|
commands from inside your game directory. If this error persists, run
|
||||||
|
|
@ -820,7 +820,7 @@ def start_evennia(pprofiler=False, sprofiler=False):
|
||||||
if response:
|
if response:
|
||||||
_, _, _, _, pinfo, sinfo = response
|
_, _, _, _, pinfo, sinfo = response
|
||||||
_print_info(pinfo, sinfo)
|
_print_info(pinfo, sinfo)
|
||||||
_reactor_stop()
|
_reactor_stop()
|
||||||
|
|
||||||
def _portal_started(*args):
|
def _portal_started(*args):
|
||||||
print(
|
print(
|
||||||
|
|
@ -1460,15 +1460,9 @@ def create_game_directory(dirname):
|
||||||
|
|
||||||
def create_superuser():
|
def create_superuser():
|
||||||
"""
|
"""
|
||||||
Auto-create the superuser account. Returns `True` if superuser was created.
|
Create the superuser account
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from evennia.accounts.models import AccountDB
|
|
||||||
|
|
||||||
if AccountDB.objects.filter(is_superuser=True).exists():
|
|
||||||
# if superuser already exists, do nothing here
|
|
||||||
return False
|
|
||||||
|
|
||||||
print(
|
print(
|
||||||
"\nCreate a superuser below. The superuser is Account #1, the 'owner' "
|
"\nCreate a superuser below. The superuser is Account #1, the 'owner' "
|
||||||
"account of the server. Email is optional and can be empty.\n"
|
"account of the server. Email is optional and can be empty.\n"
|
||||||
|
|
@ -1480,95 +1474,79 @@ def create_superuser():
|
||||||
password = environ.get("EVENNIA_SUPERUSER_PASSWORD")
|
password = environ.get("EVENNIA_SUPERUSER_PASSWORD")
|
||||||
|
|
||||||
if (username is not None) and (password is not None) and len(password) > 0:
|
if (username is not None) and (password is not None) and len(password) > 0:
|
||||||
|
from evennia.accounts.models import AccountDB
|
||||||
|
|
||||||
superuser = AccountDB.objects.create_superuser(username, email, password)
|
superuser = AccountDB.objects.create_superuser(username, email, password)
|
||||||
superuser.save()
|
superuser.save()
|
||||||
else:
|
else:
|
||||||
django.core.management.call_command("createsuperuser", interactive=True)
|
django.core.management.call_command("createsuperuser", interactive=True)
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def check_database(always_return=False):
|
def check_database(always_return=False):
|
||||||
"""
|
"""
|
||||||
Check if the database exists and has basic tables. This is only run by the launcher.
|
Check so the database exists.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
always_return (bool, optional): If True, will not raise exceptions on errors.
|
always_return (bool, optional): If set, will always return True/False
|
||||||
|
also on critical errors. No output will be printed.
|
||||||
Returns:
|
Returns:
|
||||||
exists (bool): `True` if database exists and seems set up, `False` otherwise.
|
exists (bool): `True` if the database exists, otherwise `False`.
|
||||||
If `always_return` is `False`, this will raise exceptions instead of
|
|
||||||
returning `False`.
|
|
||||||
"""
|
"""
|
||||||
# Check if database exists
|
# Check so a database exists and is accessible
|
||||||
from django.conf import settings
|
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
||||||
tables_to_check = [
|
tables = connection.introspection.get_table_list(connection.cursor())
|
||||||
"accounts_accountdb", # base account table
|
if not tables or not isinstance(tables[0], str): # django 1.8+
|
||||||
"objects_objectdb", # base object table
|
tables = [tableinfo.name for tableinfo in tables]
|
||||||
"scripts_scriptdb", # base script table
|
if tables and "accounts_accountdb" in tables:
|
||||||
"typeclasses_tag", # base tag table
|
# database exists and seems set up. Initialize evennia.
|
||||||
]
|
evennia._init()
|
||||||
|
# Try to get Account#1
|
||||||
|
from evennia.accounts.models import AccountDB
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with connection.cursor() as cursor:
|
AccountDB.objects.get(id=1)
|
||||||
# Get all table names in the database
|
except (django.db.utils.OperationalError, ProgrammingError) as e:
|
||||||
if connection.vendor == "postgresql":
|
if always_return:
|
||||||
cursor.execute(
|
return False
|
||||||
"""
|
print(ERROR_DATABASE.format(traceback=e))
|
||||||
SELECT tablename FROM pg_tables
|
sys.exit()
|
||||||
WHERE schemaname = 'public'
|
except AccountDB.DoesNotExist:
|
||||||
"""
|
# no superuser yet. We need to create it.
|
||||||
)
|
|
||||||
elif connection.vendor == "mysql":
|
|
||||||
cursor.execute(
|
|
||||||
"""
|
|
||||||
SELECT table_name FROM information_schema.tables
|
|
||||||
WHERE table_schema = %s
|
|
||||||
""",
|
|
||||||
[settings.DATABASES["default"]["NAME"]],
|
|
||||||
)
|
|
||||||
elif connection.vendor == "sqlite":
|
|
||||||
cursor.execute(
|
|
||||||
"""
|
|
||||||
SELECT name FROM sqlite_master
|
|
||||||
WHERE type='table' AND name NOT LIKE 'sqlite_%'
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
if not always_return:
|
|
||||||
raise Exception(
|
|
||||||
f"Unsupported database: {connection.vendor}"
|
|
||||||
"Evennia supports PostgreSQL, MySQL, and SQLite only."
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
existing_tables = {row[0].lower() for row in cursor.fetchall()}
|
other_superuser = AccountDB.objects.filter(is_superuser=True)
|
||||||
|
if other_superuser:
|
||||||
|
# Another superuser was found, but not with id=1. This may
|
||||||
|
# happen if using flush (the auto-id starts at a higher
|
||||||
|
# value). Wwe copy this superuser into id=1. To do
|
||||||
|
# this we must deepcopy it, delete it then save the copy
|
||||||
|
# with the new id. This allows us to avoid the UNIQUE
|
||||||
|
# constraint on usernames.
|
||||||
|
other = other_superuser[0]
|
||||||
|
other_id = other.id
|
||||||
|
other_key = other.username
|
||||||
|
print(WARNING_MOVING_SUPERUSER.format(other_key=other_key, other_id=other_id))
|
||||||
|
res = ""
|
||||||
|
while res.upper() != "Y":
|
||||||
|
# ask for permission
|
||||||
|
res = eval(input("Continue [Y]/N: "))
|
||||||
|
if res.upper() == "N":
|
||||||
|
sys.exit()
|
||||||
|
elif not res:
|
||||||
|
break
|
||||||
|
# continue with the
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
# Check if essential tables exist
|
new = deepcopy(other)
|
||||||
missing_tables = [table for table in tables_to_check if table not in existing_tables]
|
other.delete()
|
||||||
|
new.id = 1
|
||||||
if missing_tables:
|
new.save()
|
||||||
if always_return:
|
else:
|
||||||
return False
|
create_superuser()
|
||||||
raise Exception(
|
check_database(always_return=always_return)
|
||||||
f"Database tables missing: {', '.join(missing_tables)}. "
|
return True
|
||||||
"\nDid you remember to run migrations?"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
create_superuser()
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as exc:
|
|
||||||
if not always_return:
|
|
||||||
raise
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
traceback.print_exc()
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def getenv():
|
def getenv():
|
||||||
|
|
@ -1810,12 +1788,11 @@ def init_game_directory(path, check_db=True, need_gamedir=True):
|
||||||
else:
|
else:
|
||||||
os.environ["DJANGO_SETTINGS_MODULE"] = SETTINGS_DOTPATH
|
os.environ["DJANGO_SETTINGS_MODULE"] = SETTINGS_DOTPATH
|
||||||
|
|
||||||
|
# required since django1.7
|
||||||
|
django.setup()
|
||||||
|
|
||||||
# test existence of the settings module
|
# test existence of the settings module
|
||||||
try:
|
try:
|
||||||
|
|
||||||
# required since django1.7
|
|
||||||
django.setup()
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if not str(ex).startswith("No module named"):
|
if not str(ex).startswith("No module named"):
|
||||||
|
|
@ -1828,7 +1805,6 @@ def init_game_directory(path, check_db=True, need_gamedir=True):
|
||||||
# this will both check the database and initialize the evennia dir.
|
# this will both check the database and initialize the evennia dir.
|
||||||
if check_db:
|
if check_db:
|
||||||
check_database()
|
check_database()
|
||||||
evennia._init()
|
|
||||||
|
|
||||||
# if we don't have to check the game directory, return right away
|
# if we don't have to check the game directory, return right away
|
||||||
if not need_gamedir:
|
if not need_gamedir:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue