You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm just trying to get this working and get a better understanding of what went wrong and how I can recover. I really want to use this in production but this kind of blocker seems like a showstopper to me. Thanks in advance!
I have been following the Easy EdgeDB book on your website. I'm on Chapter 18: Using Dracula's own weapon against him. I just created the Money type and the abstract HasMoney type. I modified the Person type to inherit from HasMoney (using abstract type Person extending HasMoney. When I go to migrate this last change, it fails every time.
I broke up all of the prior steps into their own migrations and it succeeds. But trying to extend Person to inherit from HasMoney fails and the error output is not helpful at all.
did you alter object type 'default::Person'? [y,n,l,c,b,s,q,?]
> l
The following DDL statements will be applied:
ALTER TYPE default::Person {
EXTENDING default::HasMoney LAST;
};
did you alter object type 'default::Person'? [y,n,l,c,b,s,q,?]
> y
Error executing command: EdgeDB could not resolve migration with the provided answers. Please retry with different answers.
I have \set verbose-errors true in the REPL and this appears to do nothing to help get better errors.
I've attempted to scour the server log, but there's nothing about schema changes or migrations emitted there.
I am at a total loss. I've followed the tutorial instructions TO THE LETTER and up to this point everything has worked fine. Now I'm just stuck.
Schema:
Here is the output from my default.esdl
module default {
scalar type Money extending int64 {
delegated constraint min_value(0);
}
abstract type HasMoney {
required pounds: Money {
default := 0;
}
required shillings: Money {
default := 0;
}
required pence: Money {
default := 0;
}
required dollars: Money {
default := 0;
}
required cents: Money {
default := 0;
}
total_pence := .pounds * 240 + .shillings * 20 + .pence;
total_cents := .dollars * 100 + .cents;
approx_wealth_in_pounds := <int64>.total_pence / 240 + .total_cents / 800;
}
abstract type HasNumber {
required number: int16;
}
abstract type Person extending HasMoney {
required name: str {
delegated constraint exclusive;
}
multi places_visited: Place;
multi lovers: Person;
is_single := not exists .lovers;
age: int16;
strength: int16;
first_appearance: cal::local_date;
last_appearance: cal::local_date;
title: str;
degrees: array<str>;
conversational_name := .title ++ ' '
++ .name if exists .title else .name;
pen_name := .name ++ ', '
++ array_join(.degrees, ', ') if exists .degrees else .name;
}
type Party {
name: str;
members := .<party[is PC];
}
scalar type PCNumber extending sequence;
scalar type LotteryTicket extending enum<Nothing, WallChicken, ChainWhip, Crucifix, Garlic>;
type PC extending Person {
required class: Class;
required created_at: datetime {
default := datetime_of_statement();
}
last_updated: datetime {
rewrite insert, update using (datetime_of_statement());
}
required number: PCNumber {
default := sequence_next(introspect PCNumber);
}
overloaded required name: str {
constraint max_len_value(30);
}
multi party: Party {
# Delete the party when the last person leaves.
on source delete delete target if orphan;
on target delete allow;
}
bonus_item: LotteryTicket {
rewrite insert, update using (get_ticket());
}
}
type NPC extending Person {
overloaded age: int16 {
constraint max_value(120);
}
};
type Vampire extending Person {
multi slaves: MinorVampire {
# Delete all the slaves of a vampire when the vampire is deleted.
on source delete delete target;
property combined_strength := (Vampire.strength + .strength) / 2;
}
army_strength := sum(.slaves@combined_strength);
overloaded strength: int16 {
constraint min_value(10);
}
}
type Lord extending Person {
constraint expression on (contains(__subject__.name, 'Lord')) {
errmessage := 'Lord names must contain the word "Lord".';
}
}
abstract annotation note;
type MinorVampire extending Person {
annotation note := 'first_appearance for MinorVampire should always match last_appearance for its matching Person type';
former_self: Person;
single master := assert_single(.<slaves[is Vampire]);
master_name := .master.name;
};
type Crewman extending HasNumber, Person {
overloaded name: str {
default := 'Crewman ' ++ <str>.number;
}
};
alias CrewmanInBulgaria := Crewman {
name := 'Gospodin' ++ .name,
strength := .strength + <int16>1,
# Just in case we want to filter on the original name.
original_name := .name,
};
scalar type Rank extending enum<Captain, FirstMate, SecondMate, Cook>;
type Sailor extending Person {
rank: Rank;
}
abstract type HasNameAndCoffins {
required coffins: int16 {
default := 0;
}
required name: str {
delegated constraint exclusive;
constraint max_len_value(30);
}
}
alias AllNames := (
distinct (
HasNameAndCoffins.name union
Place.modern_name union
Landmark.name union
Person.name
)
);
type Ship extending HasNameAndCoffins {
multi sailors: Sailor;
multi crew: Crewman;
}
type Landmark {
required name: str;
multi context: str;
}
type Place extending HasNameAndCoffins {
modern_name: str;
multi important_places: Landmark;
}
type City extending Place {
annotation description := 'A place with 50 or more buildings. Anything else is an OtherPlace.';
population: int64;
index on (.name ++ ': ' ++ <str>.population) {
annotation title := 'Lists city name and population for display.';
};
};
type Country extending Place;
type Castle extending Place {
doors: array<int16>;
};
abstract annotation warning;
type OtherPlace extending Place {
annotation description := ' A place with less than 50 buildings: hamlets, small towns, etc.';
annotation warning := 'Castles and castle towns do not count! Use the Castle type for that!';
};
scalar type Class extending enum<Rogue, Mystic, Merchant>;
scalar type SleepState extending enum<Awake, Asleep>;
type Time {
required clock: str;
clock_time := <cal::local_time>.clock;
hour := .clock[0:2];
vampires_are := SleepState.Asleep if <int16>.hour > 7 and <int16>.hour < 19
else SleepState.Awake;
}
global time := assert_single((select Time));
scalar type Mode extending enum<Info, Debug>;
required global tester_mode: Mode {
default := Mode.Info;
}
function get_url() -> str
using (<str>'https://geo.hack.toolforge.org/geohack.php?params=');
type BookExcerpt {
required date: cal::local_datetime;
required excerpt: str;
index on (.date);
required author: Person;
}
type Event {
required description: str;
required start_time: cal::local_datetime;
required end_time: cal::local_datetime;
required multi place: Place;
required multi people: Person;
# multi excerpts: BookExcerpt;
location: tuple<float64, float64>;
index on (.location);
ns_suffix := '_N_' if .location.0 > 0.0 else '_S_';
ew_suffix := '_E_' if .location.1 > 0.0 else '_W_';
url := get_url()
++ <str>(math::abs(.location.0)) ++ .ns_suffix
++ <str>(math::abs(.location.1)) ++ .ew_suffix;
}
function make_string(input: int64) -> str
using (<str>input);
function fight(one: Person, two: Person) -> str
using (
one.name ++ ' wins!' if (one.strength ?? 0) > (two.strength ?? 0)
else two.name ++ ' wins!'
);
function fight(people_names: array<str>, opponent: Person) -> str
using (
with
people := (select Person filter contains(people_names, .name)),
select
array_join(people_names, ', ') ++ ' win!'
if sum(people.strength) > (opponent.strength ?? 0)
else opponent.name ++ ' wins!'
);
function visited(person: str, city: str) -> bool
using (
with person := (select Person filter .name = person),
select city in person.places_visited.name
);
function can_enter(person_name: str, place: str) -> optional str
using (
with
vampire := assert_single(
(select Person filter .name = person_name)
),
enter_place := assert_single(
(select HasNameAndCoffins filter .name = place)
)
select vampire.name ++ ' can enter.' if enter_place.coffins > 0
else vampire.name ++ ' cannot enter.'
);
function try(place: optional City) -> str
using (select 'Called!');
function get_ticket() -> LotteryTicket
using (
with
rnd := <int16>(random() * 10),
select (
LotteryTicket.Nothing if rnd <= 6 else
LotteryTicket.WallChicken if rnd = 7 else
LotteryTicket.ChainWhip if rnd = 8 else
LotteryTicket.Crucifix if rnd = 9 else
LotteryTicket.Garlic
)
);
alias GameInfo := (
title := (
en := "Dracula the Immortal",
fr := "Dracula l'immortel",
no := "Dracula den udødelige",
ro := "Dracula, nemuritorul"
),
country := "Norway",
date_published := 2023,
website := "www.draculatheimmortal.com"
);
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I'm just trying to get this working and get a better understanding of what went wrong and how I can recover. I really want to use this in production but this kind of blocker seems like a showstopper to me. Thanks in advance!
I have been following the Easy EdgeDB book on your website. I'm on Chapter 18: Using Dracula's own weapon against him. I just created the
Money
type and the abstractHasMoney
type. I modified thePerson
type to inherit fromHasMoney
(usingabstract type Person extending HasMoney
. When I go to migrate this last change, it fails every time.I broke up all of the prior steps into their own migrations and it succeeds. But trying to extend
Person
to inherit fromHasMoney
fails and the error output is not helpful at all.I have
\set verbose-errors true
in the REPL and this appears to do nothing to help get better errors.I've attempted to scour the server log, but there's nothing about schema changes or migrations emitted there.
I am at a total loss. I've followed the tutorial instructions TO THE LETTER and up to this point everything has worked fine. Now I'm just stuck.
Schema:
Here is the output from my
default.esdl
Beta Was this translation helpful? Give feedback.
All reactions