is it possible to make something like this in sqlite ?
FOREIGN KEY(TypeCode, 'ARawValue', IdServeur) REFERENCES OTHERTABLE(TypeCode, TypeElem, IdServeur)
it says unknown column "ARawValue" in foreign key definition, is't there another way ?
No, this is not possible. A foreign key constraint must be defined only by columns in the child and parent tables.
Probably the next best solution is to add a column to the child table with a default value set to the literal value (and optionally a check constraint that restricts the column to that single value).
Strictly speaking, an sqlite unique partial index should have been a good alternative solution, but it did not work for me in testing on version 3.28.0. A partial index is an index defined with a WHERE clause and can even be marked as UNIQUE. The official foreign key documentation requires a UNIQUE index on the parent table. There is no explicit exclusion of partial indexes, so I thought it would be a good solution. I was able to create the index and even define the foreign key constraint on the partial index, but no matter what I tried I got a foreign key error upon INSERT into the child table, even when I had verified that the parent table contained a unique pair of values as defined by the index.
Related
Question
Having gone through verbose AWS documentations, I need some help to clarify the basic keywords and concept of DynamoDB.
Kindly assist to confirm if these are correct.
Hash key
The key which decides the partition of the item, so it is also called as the 'partition' key.
Primary key
A hash key, or (hash-key, range-key) pair that can identify only 1 item in the table. A (hash-key, range-key) pair is also called 'composite' key.
If the primary key has only hash-key, "hash-key" and "primary-key" can be used interchangeably(but doing so can cause confusions).
Local secondary index
In a simple term, "alternative range key" to be used with the hash-key of the primary key.
Besides the range key in the primary key (hash-key, range-key), we can have additional range keys that can be used with the hash-key of the primary key.
Global secondary index
Alternative (hash-key, range-key) pairs for Query.
KeyConditions
For a query on a table, you can have conditions only on the range key portion on the table/index primary key. The hash key condition must always be equal.
Expression attribute name
Dozens of words cannot be used as its attribute name in DynamoDB table, such as status. It is a way to get around this restriction to be able to use such word by prefixing with '#'. Perhaps a design error of DyanmoDB.
Key condition expression
SQL WHERE like part of Query which needs a hash-key of the primary key. It seems it identifies the one partition to get items, then additionally we can use a range-key to narrow down items.
KeyConditions
For a query on a table/index, you can have conditions only on the table/index primary key attributes. You must always provide the partition key name and value as an EQ condition. You can optionally provide a second condition, referring to the sort(aka range) key.
Filter expression
SQL WHERE like part that can be used for both with Query and Scan but only with non-key attributes.
Filter Expressions for Query
A filter expression cannot contain partition key or sort key attributes. You need to specify those attributes in the key condition expression, not the filter expression.
If used in Query in addition to the key expression, the unmatched items are thrown away.
I am attempting to use foreign key support in SQLite to maintain referential integrity on a single-table database that has a reflexive join.
e.g.
PRAGMA foreign_keys = ON;
create table tree (
objectId text unique not null,
parentObjectID text,
foreign key (parentObjectID) references tree(parentObjectID) on delete cascade
)
The behavior that I am hoping for is that when a parent row is deleted, its children and their children are deleted as well.
However, when I attempt to delete the root row (where the expected behavior would be that every other row in the database is also deleted), I get this error:
sqlite> delete from tree where objectid = '0';
Error: foreign key mismatch
Are my expectations out of whack with with SQLite foreign key support (and delete behaviors) can provide?
Your problem is pretty simple, your FK on parentObjectId references parentObjectId rather than objectId and SQLite doesn't detect this bit of confusion until you try to use the table. If your FK is defined like this:
foreign key (parentObjectID) references tree(objectID) on delete cascade
From the fine manual:
So, in other words, misconfigured foreign key constraints that require looking at both the child and parent are DML errors. The English language error message for foreign key DML errors is usually "foreign key mismatch" but can also be "no such table" if the parent table does not exist. Foreign key DML errors are may be reported if:
The parent table does not exist, or
The parent key columns named in the foreign key constraint do not exist, or
The parent key columns named in the foreign key constraint are not the primary key of the parent table and are not subject to a unique
constraint using collating sequence specified in the CREATE TABLE, or
The child table references the primary key of the parent without specifying the primary key columns and the number of primary key
columns in the parent do not match the number of child key columns.
The third point would seem to apply here since parentObjectId is neither a PK nor constrained to be unique so that's why you don't see an error until you try to modify the table's content (i.e. use a DML statement rather than a DDL statement).
One of the database view I am trying to import using entity framework contains only two columns, one is an integer type of column and another one is an aggregate function. I am getting the following error.
The table/view does not have a primary key defined and no valid primary key could be inferred. This table/view has been excluded. To use the entity, you will need to review your schema, add the correct keys, and uncomment it.
I understand it is a known scenario and it can be fixed by either including a Key column in the view or modifying the edmx file manually.
I just wanted to know if there is some other solution other than the above two? I do not want to include an additional column in my query and making changes in edmx is not feasible as DB changes are very frequent and the edmx will be overwritten every time I update from db.
You can mark both properties as entity key directly in the designer but you must ensure that the composite value of these two properties will be always unique. If you cannot ensure that you must add another unique column anyway or you may have some other problems when working with such entity set.
I know that SQLite does not enforce foreign keys natively, but that's not my primary concern. The question is: If I declare
CREATE TABLE invoice (
invoiceID INTEGER PRIMARY KEY,
clientID INTEGER REFERENCES client(clientID),
...
)
will sqlite at least use the information that clientID is a foreign key to optimize queries and automatically index invoice.clientID, or is this constraint a real no-op?
In the SQLite Documentation it says:
... "an index should be created on the child key columns of each foreign key constraint"
ie. the index is not automatically created, but you should create one in every instance.
Even if it is not actually a no-op (a data structure describing the constraint is added to the table), foreign key related statement doesn't create any index on involved columns.
Indexes are implicitly created only in the case of PRIMARY KEY and UNIQUE statements.
For more details, check it out build.c module on the sqlite source tree:
http://www.sqlite.org/cvstrac/rlog?f=sqlite/src/build.c https://www.sqlite.org/src/file?name=src/build.c&ci=tip
I have a sqlite table that was originally created with:
PRIMARY KEY (`column`);
I now need to remove that primary key and create a new one. Creating a new one is easy, but removing the original seems to be the hard part. If I do
.indices tablename
I don't get the primary key. Some programs show the primary key as
Indexes: 1
[] PRIMARY
The index name is typically in the [].
Any ideas?
You can't.
PRAGMA INDEX_LIST('MyTable');
will give you a list of indices. This will include the automatically generated index for the primary key which will be called something like 'sqlite_autoindex_MyTable_1'.
But unfortunately you cannot drop this index...
sqlite> drop index sqlite_autoindex_MyTable_1;
SQL error: index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped
All you can do is re-create the table without the primary key.
I the database glossary; a primary-key is a type of index where the index order is typically results in the physical ordering of the raw database records. That said any database engine that allows the primary key to be changed is likely reordering the database... so most do not and the operation is up to the programmer to create a script to rename the table and create a new one. So if you want to change the PK there is no magic SQL.
select * from sqlite_master;
table|x|x|2|CREATE TABLE x (a text, b text, primary key (`a`))
index|sqlite_autoindex_x_1|x|3|
You'll see that the second row returned from my quick hack has the index name in the second column, and the table name in the third. Try seeing if that name is anything useful.