Replace all marketing placeholder content with real MYeasyCMS content
- Logo: Replace generic Makerkit SVG with MYeasyCMS branded logo (grid icon + styled text) - Blog: Replace 3 SaaS placeholder posts with 5 real articles (Vereinsverwaltung, SEPA, Website, DSGVO, Mitglieder-Tipps) - Changelog: Replace 6 generic entries with real feature announcements (Verbandsverwaltung, Fischerei, Dateien, Kurse, Einladungen, i18n) - Documentation: Rewrite all 20 docs from Makerkit references to MYeasyCMS content - FAQ: Replace 6 generic SaaS questions with 10 real MYeasyCMS questions - Navigation: Replace Changelog link with Contact in main nav - Footer: Reorganize into Product/Company/Legal sections - Translations: Update all EN marketing strings to match real Com.BISS content
This commit is contained in:
@@ -1,430 +1,34 @@
|
||||
---
|
||||
title: "Querying Data"
|
||||
description: "Learn how to query and filter data from your database."
|
||||
title: "Datenexport"
|
||||
description: "Exportieren Sie Ihre Vereinsdaten in verschiedenen Formaten — für Berichte, Auswertungen und Datensicherung."
|
||||
publishedAt: 2024-04-11
|
||||
order: 3
|
||||
order: 1
|
||||
status: "published"
|
||||
---
|
||||
|
||||
> **Note:** This is mock/placeholder content for demonstration purposes.
|
||||
MYeasyCMS bietet umfangreiche Exportmöglichkeiten für alle Ihre Vereinsdaten.
|
||||
|
||||
Efficiently query and filter data using Supabase's query builder.
|
||||
## Exportformate
|
||||
|
||||
## Basic Queries
|
||||
- **Excel (.xlsx)** — Für die Weiterverarbeitung in Tabellenkalkulationen
|
||||
- **CSV** — Universelles Format für den Datenaustausch
|
||||
- **PDF** — Für druckfertige Berichte und Dokumente
|
||||
- **SEPA XML (pain.008)** — Für den Bankeinzug per Lastschrift
|
||||
|
||||
### Select All
|
||||
## Was kann exportiert werden?
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.select('*');
|
||||
```
|
||||
### Mitgliederdaten
|
||||
Exportieren Sie die vollständige Mitgliederliste oder gefilterte Teilmengen — nach Abteilung, Status, Eintrittsdatum oder anderen Kriterien.
|
||||
|
||||
### Select Specific Columns
|
||||
### Finanzdaten
|
||||
Beitragsübersichten, offene Posten, Zahlungshistorie und SEPA-Dateien für den Bankeinzug.
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.select('id, name, created_at');
|
||||
```
|
||||
### Kurs- und Veranstaltungsdaten
|
||||
Teilnehmerlisten, Kursübersichten und Anwesenheitslisten.
|
||||
|
||||
### Select with Related Data
|
||||
### Dokumente
|
||||
Generierte Dokumente (Ausweise, Rechnungen, Briefe) als PDF herunterladen.
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.select(`
|
||||
id,
|
||||
name,
|
||||
account:accounts(id, name),
|
||||
tasks(id, title, completed)
|
||||
`);
|
||||
```
|
||||
## Datensicherung
|
||||
|
||||
## Filtering
|
||||
|
||||
### Equal
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.eq('status', 'active');
|
||||
```
|
||||
|
||||
### Not Equal
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.neq('status', 'deleted');
|
||||
```
|
||||
|
||||
### Greater Than / Less Than
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.gt('created_at', '2024-01-01')
|
||||
.lt('budget', 10000);
|
||||
```
|
||||
|
||||
### In Array
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.in('status', ['active', 'pending']);
|
||||
```
|
||||
|
||||
### Like (Pattern Matching)
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.like('name', '%website%');
|
||||
```
|
||||
|
||||
### Full-Text Search
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.textSearch('description', 'design & development');
|
||||
```
|
||||
|
||||
## Ordering
|
||||
|
||||
### Order By
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.order('created_at', { ascending: false });
|
||||
```
|
||||
|
||||
### Multiple Order By
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.order('status')
|
||||
.order('created_at', { ascending: false });
|
||||
```
|
||||
|
||||
## Pagination
|
||||
|
||||
### Limit
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.limit(10);
|
||||
```
|
||||
|
||||
### Range (Offset)
|
||||
|
||||
```typescript
|
||||
const page = 2;
|
||||
const pageSize = 10;
|
||||
const from = (page - 1) * pageSize;
|
||||
const to = from + pageSize - 1;
|
||||
|
||||
const { data, count } = await client
|
||||
.from('projects')
|
||||
.select('*', { count: 'exact' })
|
||||
.range(from, to);
|
||||
```
|
||||
|
||||
## Aggregations
|
||||
|
||||
### Count
|
||||
|
||||
```typescript
|
||||
const { count } = await client
|
||||
.from('projects')
|
||||
.select('*', { count: 'exact', head: true });
|
||||
```
|
||||
|
||||
### Count with Filters
|
||||
|
||||
```typescript
|
||||
const { count } = await client
|
||||
.from('projects')
|
||||
.select('*', { count: 'exact', head: true })
|
||||
.eq('status', 'active');
|
||||
```
|
||||
|
||||
## Advanced Queries
|
||||
|
||||
### Multiple Filters
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.eq('account_id', accountId)
|
||||
.eq('status', 'active')
|
||||
.gte('created_at', startDate)
|
||||
.lte('created_at', endDate)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(20);
|
||||
```
|
||||
|
||||
### OR Conditions
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.or('status.eq.active,status.eq.pending');
|
||||
```
|
||||
|
||||
### Nested OR
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.or('and(status.eq.active,priority.eq.high),status.eq.urgent');
|
||||
```
|
||||
|
||||
## Joins
|
||||
|
||||
### Inner Join
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select(`
|
||||
*,
|
||||
account:accounts!inner(
|
||||
id,
|
||||
name
|
||||
)
|
||||
`)
|
||||
.eq('account.name', 'Acme Corp');
|
||||
```
|
||||
|
||||
### Left Join
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select(`
|
||||
*,
|
||||
tasks(*)
|
||||
`);
|
||||
```
|
||||
|
||||
## Null Handling
|
||||
|
||||
### Is Null
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.is('completed_at', null);
|
||||
```
|
||||
|
||||
### Not Null
|
||||
|
||||
```typescript
|
||||
const { data} = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.not('completed_at', 'is', null);
|
||||
```
|
||||
|
||||
## Insert Data
|
||||
|
||||
### Single Insert
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.insert({
|
||||
name: 'New Project',
|
||||
account_id: accountId,
|
||||
status: 'active',
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
```
|
||||
|
||||
### Multiple Insert
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.insert([
|
||||
{ name: 'Project 1', account_id: accountId },
|
||||
{ name: 'Project 2', account_id: accountId },
|
||||
])
|
||||
.select();
|
||||
```
|
||||
|
||||
## Update Data
|
||||
|
||||
### Update with Filter
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.update({ status: 'completed' })
|
||||
.eq('id', projectId)
|
||||
.select()
|
||||
.single();
|
||||
```
|
||||
|
||||
### Update Multiple Rows
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.update({ status: 'archived' })
|
||||
.eq('account_id', accountId)
|
||||
.lt('updated_at', oldDate);
|
||||
```
|
||||
|
||||
## Delete Data
|
||||
|
||||
### Delete with Filter
|
||||
|
||||
```typescript
|
||||
const { error } = await client
|
||||
.from('projects')
|
||||
.delete()
|
||||
.eq('id', projectId);
|
||||
```
|
||||
|
||||
### Delete Multiple
|
||||
|
||||
```typescript
|
||||
const { error } = await client
|
||||
.from('projects')
|
||||
.delete()
|
||||
.in('id', projectIds);
|
||||
```
|
||||
|
||||
## Upsert
|
||||
|
||||
### Insert or Update
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.upsert({
|
||||
id: projectId,
|
||||
name: 'Updated Name',
|
||||
status: 'active',
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
```
|
||||
|
||||
## RPC (Stored Procedures)
|
||||
|
||||
### Call Database Function
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.rpc('get_user_projects', {
|
||||
user_id: userId,
|
||||
});
|
||||
```
|
||||
|
||||
### With Complex Parameters
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.rpc('search_projects', {
|
||||
search_term: 'design',
|
||||
account_ids: [1, 2, 3],
|
||||
min_budget: 5000,
|
||||
});
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Basic Error Handling
|
||||
|
||||
```typescript
|
||||
const { data, error } = await client
|
||||
.from('projects')
|
||||
.select('*');
|
||||
|
||||
if (error) {
|
||||
console.error('Error fetching projects:', error.message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data;
|
||||
```
|
||||
|
||||
### Typed Error Handling
|
||||
|
||||
```typescript
|
||||
import { PostgrestError } from '@supabase/supabase-js';
|
||||
|
||||
function handleDatabaseError(error: PostgrestError) {
|
||||
switch (error.code) {
|
||||
case '23505': // unique_violation
|
||||
throw new Error('A project with this name already exists');
|
||||
case '23503': // foreign_key_violation
|
||||
throw new Error('Invalid account reference');
|
||||
default:
|
||||
throw new Error('Database error: ' + error.message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## TypeScript Types
|
||||
|
||||
### Generated Types
|
||||
|
||||
```typescript
|
||||
import { Database } from '~/types/database.types';
|
||||
|
||||
type Project = Database['public']['Tables']['projects']['Row'];
|
||||
type ProjectInsert = Database['public']['Tables']['projects']['Insert'];
|
||||
type ProjectUpdate = Database['public']['Tables']['projects']['Update'];
|
||||
```
|
||||
|
||||
### Typed Queries
|
||||
|
||||
```typescript
|
||||
const { data } = await client
|
||||
.from('projects')
|
||||
.select('*')
|
||||
.returns<Project[]>();
|
||||
```
|
||||
|
||||
## Performance Tips
|
||||
|
||||
1. **Select only needed columns** - Don't use `select('*')` unnecessarily
|
||||
2. **Use indexes** - Create indexes on frequently filtered columns
|
||||
3. **Limit results** - Always paginate large datasets
|
||||
4. **Avoid N+1 queries** - Use joins instead of multiple queries
|
||||
5. **Use RPC for complex queries** - Move logic to database
|
||||
6. **Cache when possible** - Use React Query or similar
|
||||
7. **Profile queries** - Use `EXPLAIN ANALYZE` in SQL
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always handle errors** - Check error responses
|
||||
2. **Validate input** - Use Zod or similar
|
||||
3. **Use TypeScript** - Generate and use types
|
||||
4. **Consistent naming** - Follow database naming conventions
|
||||
5. **Document complex queries** - Add comments
|
||||
6. **Test queries** - Unit test database operations
|
||||
7. **Monitor performance** - Track slow queries
|
||||
Für die eigene Datensicherung können Sie regelmäßig einen Gesamtexport Ihrer Mitgliederdaten erstellen. Dies dient als zusätzliche Sicherheit neben den automatischen Server-Backups.
|
||||
|
||||
Reference in New Issue
Block a user